home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1993 / Internet Info CD-ROM (Walnut Creek) (1993).iso / security / log_tcp_5.1.shar < prev    next >
Internet Message Format  |  1993-03-24  |  151KB

  1. From wietse@wzv.win.tue.nl  Wed Mar 24 23:37:23 1993
  2. Received: from svin01.win.tue.nl by svbs01.bs.win.tue.nl (4.1/1.45)
  3.     id AA16728; Wed, 24 Mar 93 23:37:23 +0100
  4. Received: from svin09.info.win.tue.nl by svin01.win.tue.nl (4.1/1.45)
  5.     id AA00471; Wed, 24 Mar 93 23:37:18 +0100
  6. Received: from wzv.win.tue.nl by svin09.info.win.tue.nl (4.1/1.45)
  7.     id AA02366; Wed, 24 Mar 93 23:33:04 +0100
  8. Received: by wzv.win.tue.nl (4.1/1.45)
  9.     id AA01314; Wed, 24 Mar 93 23:06:25 +0100
  10. Date: Wed, 24 Mar 93 23:06:25 +0100
  11. From: wietse@wzv.win.tue.nl (Wietse Venema)
  12. Message-Id: <9303242206.AA01314@wzv.win.tue.nl>
  13. To: ecd@cert.org
  14. Subject: tcp wrapper reveals SunOS 4.x kernel bug
  15. Cc: wswietse@win.tue.nl
  16. Status: OR
  17.  
  18. The new wrapper release causes occasional kernel panics with SunOS 4.x.
  19. There is a bug in the getsockopt() system call implementation.
  20.  
  21. Getsockopt() was used to detect source-routing attacks. That code was
  22. enabled by default. I have changed this: by default the code no longer
  23. tries to expose source-routing attacks.
  24.  
  25. The result of this effort is below. Changes were made only to the
  26. documentation, to the Makefile, and to the patchlevel.h file.
  27.  
  28. Please replace the wrapper archives on cert.org. I will post a separate
  29. message to the cert-tools mailing list.
  30.  
  31.     Wietse
  32. --------------
  33.  
  34. With the programs that come with this kit you can monitor incoming
  35. requests for IP services such as TFTP, EXEC, FTP, RSH, TELNET, RLOGIN,
  36. FINGER, SYSTAT, and many others.
  37.  
  38. Optional features are: access control based on pattern matching; remote
  39. username lookup using the RFC 931 protocol; protection against attacks
  40. from hosts that pretend to have someone elses name; protection against
  41. attacks from hosts that pretend to have someone elses network address.
  42.  
  43. The programs can be installed without requiring any changes to existing
  44. software or configuration files. By default, they just log the remote
  45. host name and do some sanity checks on the origin the request. No
  46. information is exchanged with the remote client process.
  47.  
  48. The most notable differences with respect to the previous release are:
  49.  
  50.     - Optional protection against attacks from hosts that pretend to
  51.     have someone elses network address. For example, the address of a
  52.     trusted host within your own network.
  53.  
  54.     - The access control language has been extended with a simple but
  55.     powerful operator that greatly simplifies the design of rule sets
  56.     (ALL: .foo.edu EXCEPT dialup.foo.edu). Blank lines are permitted,
  57.     and long lines can be continued with backslash-newline.
  58.  
  59.     - All configurable stuff, including path names, has been moved into
  60.     the Makefile so that you no longer have to hack source code to just
  61.     configure the programs.
  62.  
  63.     - Ported to Solaris 2. TLI-based applications not yet supported.
  64.     Several workarounds for System V bugs.
  65.  
  66.     - A small loophole in the netgroup lookup code was closed, and the
  67.     remote username lookup code was made more portable.
  68.  
  69.     - Still more documentation. The README file now provides tutorial
  70.     sections with introductions to client, server, inetd and syslogd.
  71.  
  72. The default mode of operation should be backwards compatible with
  73. earlier versions.
  74.  
  75.     Wietse Venema (wietse@wzv.win.tue.nl),
  76.     Department of Mathematics and Computing Science,
  77.     Eindhoven University of Technology,
  78.     The Netherlands.
  79.  
  80.  
  81. #! /bin/sh
  82. # This is a shell archive.  Remove anything before this line, then unpack
  83. # it by saving it into a file and typing "sh file".  To overwrite existing
  84. # files, type "sh file -c".  You can also feed this as standard input via
  85. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  86. # will see the following message at the end:
  87. #        "End of shell archive."
  88. # Contents:  README miscd.c tcpd.c fromhost.c hosts_access.c
  89. #   shell_cmd.c log_tcp.h try.c refuse.c Makefile.dist hosts_access.5
  90. #   strcasecmp.c BLURB rfc931.c tcpd.8 hosts_info.c hosts_access.3
  91. #   hosts_ctl.c percent_x.c options.c clean_exit.c setenv.c
  92. #   patchlevel.h strtok.c fix_options.c inet_addr_fix
  93. # Wrapped by wietse@wzv on Wed Mar 24 22:44:58 1993
  94. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  95. if test -f README -a "${1}" != "-c" ; then 
  96.   echo shar: Will not over-write existing file \"README\"
  97. else
  98. echo shar: Extracting \"README\" \(34888 characters\)
  99. sed "s/^X//" >README <<'END_OF_README'
  100. X@(#) README 1.10 93/03/24 22:42:46
  101. X
  102. X
  103. XTable of contents
  104. X-----------------
  105. X
  106. X    1 - Introduction
  107. X    2 - Disclaimer
  108. X    3 - Tutorials
  109. X        3.1 - How it works
  110. X        3.2 - Where the logging information goes
  111. X    4 - Features
  112. X        4.1 - Access control
  113. X        4.2 - Host name spoofing
  114. X        4.3 - Host address spoofing
  115. X        4.4 - Remote username lookups
  116. X        4.5 - Language extension hooks
  117. X    5 - Other works
  118. X        5.1 - Related documents
  119. X        5.2 - Related software
  120. X    6 - Limitations
  121. X        6.1 - Known wrapper limitations
  122. X        6.2 - Known system software bugs
  123. X    7 - Configuration and installation
  124. X        7.1 - Easy configuration and installation
  125. X        7.2 - Advanced configuration and installation
  126. X        7.3 - Daemons with arbitrary path names
  127. X        7.4 - Building and testing the access control rules
  128. X        7.5 - Other applications
  129. X    8 - Acknowledgements
  130. X
  131. X1 - Introduction
  132. X----------------
  133. X
  134. XWith this package you can monitor incoming connections to the SYSTAT,
  135. XFINGER, FTP, TELNET, RLOGIN, RSH, EXEC, TFTP, TALK, and other network
  136. Xservices.  
  137. X
  138. XThe package provides tiny daemon wrapper programs that can be installed
  139. Xwithout any changes to existing software or to existing configuration
  140. Xfiles.  The wrappers report the name of the remote host and of the
  141. Xrequested service; the wrappers do not exchange information with the
  142. Xremote client process, and impose no overhead on the actual
  143. Xcommunication between the client and server applications.
  144. X
  145. XOptional features are: access control to restrict what systems can
  146. Xconnect to your network daemons; remote user name lookups with the RFC
  147. X931 protocol; additional protection against hosts that pretend to have
  148. Xsomeone elses host name; additional protection against hosts that
  149. Xpretend to have someone elses host address.
  150. X
  151. XEarly versions of the programs were tested with Ultrix >= 2.2, with
  152. XSunOS >= 3.4 and ISC 2.2. Later versions have been installed on a wide
  153. Xvariety of platforms such as SunOS 4.x and 5.x, Ultrix 3.x and 4.x, DEC
  154. XOSF/1 T1.2-2, HP-UX 8.x, AIX 3.1.5, Apollo SR10.3.5, Sony, NeXT, SCO
  155. XUNIX, DG/UX, Cray, and an unknown number of other ones.  
  156. X
  157. XRequirements are that the network daemons are spawned by a super server
  158. Xsuch as the inetd; a 4.3BSD-style socket programming interface; and the
  159. Xavailability of a syslog(3) library and of a syslogd(8) daemon.  The
  160. Xwrappers should run without modification on any system that satisfies
  161. Xthese requirements.  Workarounds have been implemented for several
  162. Xcommon bugs in systems software.
  163. X
  164. XWhat to do if this is your first encounter with the wrapper programs:
  165. X1) read the tutorial sections for an introduction to the relevant
  166. Xconcepts and terminology; 2) glance over the security feature sections
  167. Xin this document; 3) follow the installation instructions (easy or
  168. Xadvanced). I recommend that you first use the default security feature
  169. Xsettings.  Run the wrappers for a few days to become familiar with
  170. Xtheir logs, before doing anything drastic such as cutting off access or
  171. Xinstalling booby traps.
  172. X
  173. X2 - Disclaimer
  174. X--------------
  175. X
  176. XThe wrapper programs rely on source address information obtained from
  177. Xnetwork packets. Such information is not 100 percent reliable, although
  178. Xthe wrappers do their best to expose forgeries.
  179. X
  180. XIn the absence of cryptographic protection of message contents, and of
  181. Xcryptographic authentication of message originators, all data from the
  182. Xnetwork should be treated with sound scepticism.
  183. X
  184. XTHIS RESTRICTION IS BY NO MEANS SPECIFIC TO THE TCP/IP PROTOCOLS.
  185. X
  186. X3 - Tutorials
  187. X-------------
  188. X
  189. XThe tutorial sections give a gentle introduction to the operation of
  190. Xthe wrapper programs, and introduce some of the terminology that is
  191. Xused in the remainder of the document: client, server, the inetd and
  192. Xsyslogd daemons, and their configuration files.
  193. X
  194. X3.1 - How it works
  195. X------------------
  196. X
  197. XAlmost every application of the TCP/IP protocols is based on a client-
  198. Xserver model. For example, when a user invokes the telnet command to
  199. Xconnect to one of your systems, a telnet server process is executed on
  200. Xthe target host. The telnet server process connects the user to a login
  201. Xprocess. A few examples of client and server programs are shown in the
  202. Xtable below:
  203. X
  204. X              client   server    application
  205. X              --------------------------------
  206. X              telnet   telnetd   remote login
  207. X              ftp      ftpd      file transfer
  208. X              finger   fingerd   show users
  209. X
  210. XThe usual approach is to run one single daemon process that waits for
  211. Xall kinds of incoming network connections. Whenever a connection is
  212. Xestablished, this daemon (usually called inetd) runs the appropriate
  213. Xserver program and goes back to sleep, waiting for other connections.
  214. X
  215. XThe wrapper programs rely on a simple, but powerful mechanism.  Instead
  216. Xof directly running the desired server program, the inetd is tricked
  217. Xinto running a small wrapper program. The wrapper logs the remote host
  218. Xname or address and performs some additional checks.  When all is well,
  219. Xthe wrapper executes the desired server program and goes away.
  220. X
  221. XThe wrapper programs have no interaction with the remote user (or
  222. Xclient process).  This has two major advantages: 1) the wrappers are
  223. Xapplication-independent, so that the same program can protect many
  224. Xkinds of network services; 2) no interaction also means that the
  225. Xwrappers are invisible from outside (at least for regular users).
  226. X
  227. XAnother important property is that the wrapper programs are active only
  228. Xwhen the initial contact between client and server is established. Once
  229. Xa wrapper has done its work there is no overhead on the client-server
  230. Xcommunication.
  231. X
  232. XThe simple mechanism has one major drawback: since the wrappers go away
  233. Xafter the initial contact between client and server processes, the
  234. Xwrappers are of little use with network daemons that service more than
  235. Xone client.  The wrappers would only see the first client attempt to
  236. Xcontact such a server. The NFS mount daemon is a typical example of
  237. Xa daemon that services requests from multiple clients.
  238. X
  239. XThere are two ways to use the wrapper programs:
  240. X
  241. X1) The easy way: move network daemons to some other directory and fill
  242. X   the resulting holes with copies of the wrapper programs.  This
  243. X   approach involves no changes to configuration files, so there is
  244. X   very little risk of breaking things.
  245. X
  246. X2) The advanced way: leave the network daemons alone and modify the
  247. X   inetd configuration file.  For example, an entry such as:
  248. X
  249. X     tftp  dgram  udp  wait  root  /usr/etc/tcpd  in.tftpd -s /tftpboot
  250. X
  251. X   When a tftp request arrives, inetd will run the wrapper program
  252. X   (tcpd) with a process name `in.tftpd'.  This is the name that the
  253. X   wrapper will use when logging the request and when scanning the
  254. X   optional access control tables.  `in.tftpd' is also the name of the
  255. X   server program that the wrapper will attempt to run when all is
  256. X   well.  Any arguments (`-s /tftpboot' in this particular example) are
  257. X   transparently passed on to the server program.
  258. X
  259. XFor an account of the history of the wrapper programs, with real-life
  260. Xexamples, see the section below on related documents.
  261. X
  262. X3.2 - Where the logging information goes
  263. X----------------------------------------
  264. X
  265. XThe wrapper programs send their logging information to the syslog
  266. Xdaemon (syslogd). The disposition of the wrapper logs is determined by
  267. Xthe syslog configuration file (usually /etc/syslog.conf). Messages are
  268. Xwritten to files, to the console, or are forwarded to a @loghost.
  269. X
  270. XOlder syslog implementations (still found on Ultrix systems) only
  271. Xsupport priority levels ranging from 9 (debug-level messages) to 0
  272. X(alerts). All logging information of the same priority level (or more
  273. Xurgent) is written to the same destination.  In the syslog.conf file,
  274. Xpriority levels are specified in numerical form.  For example,
  275. X
  276. X    8/usr/spool/mqueue/syslog
  277. X
  278. Xcauses all messages with priority 8 (informational messages), and
  279. Xanything that is more urgent, to be appended to the file
  280. X/usr/spool/mqueue/syslog.
  281. X
  282. XNewer syslog implementations support message classes in addition to
  283. Xpriority levels.  Examples of message classes are: mail, daemon, auth
  284. Xand news. In the syslog.conf file, priority levels are specified with
  285. Xsymbolic names: debug, info, notice, ..., emerg. For example,
  286. X
  287. X    mail.debug            /var/log/syslog
  288. X
  289. Xcauses all messages of class mail with priority debug (or more urgent)
  290. Xto be appended to the /var/log/syslog file.
  291. X
  292. XBy default, the wrapper logs go to the same place as the transaction
  293. Xlogs of the sendmail daemon. The disposition can be changed by editing
  294. Xthe Makefile and/or the syslog.conf file. Send a `kill -HUP' to the
  295. Xsyslogd after changing its configuration file. Remember that syslogd,
  296. Xjust like sendmail, insists on one or more TABs between the left-hand
  297. Xside and the right-hand side expressions in its configuration file.
  298. X
  299. X4 - Features
  300. X------------
  301. X
  302. X4.1 - Access control
  303. X--------------------
  304. X
  305. XWhen compiled with -DHOSTS_ACCESS, the wrapper programs support a
  306. Xsimple form of access control.  Access can be controlled per host, per
  307. Xservice, or combinations thereof. The software provides hooks for the
  308. Xexecution of shell commands when an access control rule fires; this
  309. Xfeature may be used to install "booby traps".  For details, see the
  310. Xhosts_access.5 manual page, which is in `nroff -man' format. A later
  311. Xsection describes how you can test your access control rules.
  312. X
  313. XAccess control is enabled by default. It can be turned off by editing
  314. Xthe Makefile, or by providing no access control tables. The install
  315. Xinstructions below describe the Makefile editing process.
  316. X
  317. X4.2 - Host name spoofing
  318. X------------------------
  319. X
  320. XWith some network applications, such as RSH or RLOGIN, the remote host
  321. Xname plays an important role in the authentication process. Host name
  322. Xinformation can be reliable when lookups are done from a _local_ hosts
  323. Xtable, provided that the client IP address can be trusted.
  324. X
  325. XWith _distributed_ name services, authentication schemes that rely on
  326. Xhost names become more problematic. The security of your system now may
  327. Xdepend on some far-away DNS (domain name server) outside your own
  328. Xcontrol. Paradoxically, running NIS (YP) can actually improve hostname
  329. Xsecurity because it provides you with the equivalent of a local hosts
  330. Xfile.
  331. X
  332. XThe wrapper programs verify the remote host name that is returned by
  333. Xthe address->name DNS server, by asking for a second opinion.  To this
  334. Xend, the programs look at the name and addresses that are returned by
  335. Xthe name->address DNS server. If any discrepancies are found, the
  336. Xwrappers conclude that at least one of the two name servers is lying,
  337. Xand assume that they are dealing with a host that pretends to have
  338. Xsomeone elses host name.
  339. X
  340. XWhen the wrappers are unable to verify the remote host name (the
  341. Xaddress->name lookup succeeds but the name->address lookup fails), they
  342. Xalso assume that the host name is wrong. 
  343. X
  344. XWhen the remote host name is unavailable (the address->name lookup
  345. Xfails) the wrappers just use the remote host address when logging the
  346. Xconnection and when consulting the optional access control tables.
  347. X
  348. XWhen the sources are compiled with -DPARANOID, the wrappers will drop
  349. Xthe connection in case of a host name/address mismatch. When the
  350. Xsources are not compiled with -DPARANOID, the wrappers just pretend
  351. Xthat the host name is unknown when logging the connection and when
  352. Xconsulting the optional access control tables.
  353. X
  354. XParanoid mode is enabled by default. It can be turned off by editing
  355. Xthe Makefile. The configuration and installation below describes the
  356. XMakefile editing process.
  357. X
  358. X4.3 - Host address spoofing
  359. X---------------------------
  360. X
  361. XWhile host name spoofing can be found out by asking a second opinion,
  362. Xit is much harder to find out that a host claims to have someone elses
  363. Xnetwork address. And since host names are deduced from network
  364. Xaddresses, address spoofing is at least as effective as name spoofing.
  365. X
  366. XThe wrapper programs can give additional protection against hosts that
  367. Xclaim to have an address that lies outside their own network.  For
  368. Xexample, some far-away host that claims to be a trusted host within
  369. Xyour own network. Such things are possible even while the impersonated
  370. Xsystem is up and running.
  371. X
  372. XThis additional protection is not an invention of my own; it has been
  373. Xpresent for at least five years in the BSD rsh and rlogin daemons.
  374. XUnfortunately, that feature was added *after* 4.3 BSD came out, so that
  375. Xvery few, if any, UNIX vendors have adopted it.  Our site, and many
  376. Xother ones, has been running these enhanced daemons for several years,
  377. Xand without any ill effects.
  378. X
  379. XWhen the programs are compiled with -DKILL_IP_OPTIONS, source routing
  380. Xwill be disabled for all TCP connections that are handled by the
  381. Xwrapper programs.
  382. X
  383. XAll this cannot be used with SunOS 4.x because of a kernel bug in the
  384. Ximplementation of the getsockopt() system call. Kernel panics have been
  385. Xreported for SunOS 4.1.1 and SunOS 4.1.2. The symptoms are "BAD TRAP"
  386. Xand "Data fault" while executing the tcp_ctloutput() kernel function.
  387. X
  388. XThe feature is disabled by default. It can be turned on by editing the
  389. XMakefile.  The configuration and installation section below describes
  390. Xthe Makefile editing process.
  391. X
  392. XUDP services do not benefit from this additional protection. With UDP,
  393. Xall you can be certain of is the network packet's destination address.
  394. X
  395. X4.4 - Remote username lookups
  396. X-----------------------------
  397. X
  398. XThe protocol proposed in RFC 931 provides a means to get the remote
  399. Xuser name from the client host.  The requirement is that the client
  400. Xhost runs an RFC 931-compliant daemon. The information provided by such
  401. Xa daemon is not intended to be used for authentication purposes, but it
  402. Xcan provide additional information about the owner of a TCP connection.
  403. X
  404. XRemote user name lookups are enabled when the wrappers are compiled
  405. Xwith -DRFC931.  There are some limitations: the number of hosts that
  406. Xrun an RFC 931 (or compatible) daemon is small (but growing); remote
  407. Xuser name lookups do not work for datagram (UDP) connections. More
  408. Xseriously, remote user name lookups can cause noticeable delays with
  409. Xconnections from non-UNIX PCs. The wrappers use a 30-second timeout for
  410. XRFC931 lookups, to accommodate slow networks and slow hosts. 
  411. X
  412. XBy default, remote username lookups are not enabled. You can enable
  413. Xthem by editing the Makefile. The remote username lookup timeout period
  414. X(30 seconds default) can also be changed by editing the Makefile. The
  415. Xinstallation sections below describe the Makefile editing process.
  416. X
  417. XThe RFC 931 protocol has diverged into different directions (IDENT and
  418. XTAP). To add to the confusion, both protocols use the same network
  419. Xport.  The daemon wrappers implement a common subset of the protocols.
  420. X
  421. X4.5 - Language extension hooks
  422. X------------------------------
  423. X
  424. XThe wrappers sport only a limited number of features. This is for a
  425. Xgood reason: programs that are run at high privilege levels must be
  426. Xeasy to verify.
  427. X
  428. XHowever, some sites have very specific needs.  The options.c file
  429. Xprovides a framework for adding extensions to the access control
  430. Xlanguage. It comes with sample extensions that:  (1) switch to another
  431. Xuser or group id; (2) perform remote user name lookups; (3) run an
  432. Xalternate server program (this allows you to produce customized bounce
  433. Xmessages or to do really nasty stuff); (4) set arbitrary environment
  434. Xvariables; (5) change the default file protection mask.
  435. X
  436. XThe language extension hook is not enabled by default because it
  437. Xintroduces an incompatible change to the access control language
  438. Xsyntax. Instructions to enable the extensions are given in the
  439. XMakefile.
  440. X
  441. X5 - Other works
  442. X---------------
  443. X
  444. X5.1 - Related documents
  445. X-----------------------
  446. X
  447. XThe war story behind the wrapper tools is described in:
  448. X
  449. X    W.Z. Venema, "TCP WRAPPER, network monitoring, access control and
  450. X    booby traps", UNIX Security Symposium III Proceedings (Baltimore),
  451. X    September 1992. 
  452. X
  453. X    ftp.win.tue.nl:/pub/security/tcp_wrapper.ps.Z (postscript)
  454. X    ftp.win.tue.nl:/pub/security/tcp_wrapper.txt.Z (flat text)
  455. X
  456. XThe same cracker is also described in:
  457. X
  458. X    W.R. Cheswick, "An Evening with Berferd, In Which a Cracker is
  459. X    Lured, Endured, and Studied", Proceedings of the Winter USENIX
  460. X    Conference (San Francisco), January 1992.
  461. X
  462. X    research.att.com:/dist/internet_security/berferd.ps
  463. X
  464. X5.2 - Related software
  465. X----------------------
  466. X
  467. XNetwork daemons etc. with enhanced logging capabilities can generate
  468. Xmassive amounts of information: our 100+ workstations generate several
  469. Xhundred kbytes each day. egrep-based filters can help to suppress some
  470. Xof the noise.  A more powerful tool is the Swatch monitoring system by
  471. XStephen E. Hansen and E. Todd Atkins. Swatch can process log files in
  472. Xreal time and can associate arbitrary actions with patterns; its
  473. Xapplications are by no means restricted to security.  Swatch is
  474. Xavailable from sierra.stanford.edu, directory /pub/sources.
  475. X
  476. XSocks, described in the UNIX Security III proceedings, can be used to
  477. Xcontrol network traffic from hosts on an internal network, through a
  478. Xfirewall host, to the outer world. Socks consists of a daemon that is
  479. Xrun on the firewall host, and of a library with routines that redirect
  480. Xapplication socket calls through the firewall daemon.  Socks is
  481. Xavailable from s1.gov in /pub/socks.tar.Z.
  482. X
  483. XVersions of rshd and rlogind, modified to report the remote user name
  484. Xin addition to the remote host name, are available for anonymous ftp
  485. X(ftp.win.tue.nl:/pub/security/logdaemon-2.tar.Z).  These programs are
  486. Xdrop-in replacements for SunOS 4.x, Ultrix 4.x, and SunOS 5.x.
  487. X
  488. XThe securelib shared library by William LeFebvre can be used to control
  489. Xaccess to network daemons that are not run under control of the inetd,
  490. Xsuch as the RPC daemons that run until the machine goes down.
  491. XAvailable from eecs.nwu.edu, file /pub/securelib.tar.
  492. X
  493. XWhere shared libraries or router-based packet filtering are not an
  494. Xoption, an alternative portmap daemon can help to improve RPC security,
  495. Xin particular that of NFS and of the NIS (YP) information service.
  496. Xftp.win.tue.nl:/pub/security/portmap.shar.Z was tested with SunOS 4.1.1
  497. Xand 4.1.2, Ultrix 3.0 and Ultrix 4.x, HP-UX 8.x and AIX. The protection
  498. Xis less effective than that of the securelib library because portmap is
  499. Xmostly a dictionary service.  SunOS 4.x users should install the latest
  500. Xrevision of the portmap and NIS daemons instead, or adopt NIS+ which
  501. Xhas access control built in.
  502. X
  503. XSource for a portable RFC 931 (TAP, IDENT)-compatible daemon by Peter
  504. XEriksson is available from ftp.lysator.liu.se:/pub/ident/servers.
  505. X
  506. XSome TCP/IP implementations come without syslog library. Some come with
  507. Xthe library but have no syslog daemon. A replacement can be found in
  508. Xftp.win.tue.nl:/pub/security/surrogate-syslog.tar.Z.  The fakesyslog
  509. Xlibrary that comes with the nntp sources reportedly works well, too.
  510. X
  511. X6 - Limitations
  512. X---------------
  513. X
  514. X6.1 - Known wrapper limitations
  515. X-------------------------------
  516. X
  517. XSome UDP (and RPC) daemons linger around for a while after they have
  518. Xserviced a request, just in case another request comes in.  In the
  519. Xinetd configuration file these daemons are registered with the `wait'
  520. Xoption. Only the request that started such a daemon will be seen by the
  521. Xwrappers.  This restriction does not apply to connection-oriented (TCP)
  522. Xservices.
  523. X
  524. XTLI (transport level interface), the System V stream-based and
  525. Xprotocol-independent network programming interface, is not yet
  526. Xsupported, but we're working on it.
  527. X
  528. XThe wrappers do not work with RPC services over TCP. These services are
  529. Xregistered as rpc/tcp in the inetd configuration file. The only non-
  530. Xtrivial service that is affected by this limitation is rexd, which is
  531. Xused by the on(1) command. This is no great loss.  On most systems,
  532. Xrexd is less secure than a wildcard in /etc/hosts.equiv.
  533. X
  534. XRPC broadcast requests (for example: rwall, rup, rusers) always appear
  535. Xto come from the responding host. What happens is that the client
  536. Xbroadcasts its request to all portmap daemons on its network; each
  537. Xportmap daemon forwards the request to its own system. As far as the
  538. Xrwall etc.  daemons know, the request comes from the local host.
  539. X
  540. XPortmap and RPC (e.g. NIS and NFS) security is a topic in itself. See
  541. Xthe section in this document on related software.
  542. X
  543. X6.2 - Known system software bugs
  544. X--------------------------------
  545. X
  546. XWorkarounds have been implemented for several bugs in system software.
  547. XThey are described in the Makefile. Unfortunately, some system software
  548. Xbugs cannot be worked around. The result is loss of functionality.
  549. X
  550. XOlder ConvexOS versions come with a broken recvfrom(2) implementation.
  551. XThis makes it impossible for the daemon wrappers to look up the
  552. Xremote host address (and hence, the name) in case of UDP requests.
  553. XA patch is available for ConvexOS 10.1; later releases should be OK.
  554. X
  555. XOn some systems, the optional RFC 931 remote username lookups may
  556. Xtrigger a kernel bug.  When a client host connects to your system, and
  557. Xthe RFC 931 connection from your system to that client is rejected by a
  558. Xrouter, your kernel may drop all connections with that client.  This is
  559. Xnot a bug in the wrapper programs: complain to your vendor, and don't
  560. Xenable remote user name lookups until the bug has been fixed.
  561. X
  562. XReportedly, SunOS 4.1.1, Next 2.0a, ISC 3.0 with TCP 1.3, and AIX 3.2.2
  563. Xare OK.
  564. X
  565. XSony News/OS 4.51, HP-UX 8-something and Ultrix 4.3 still have the bug.
  566. XAt the time of writing, a fix for Ultrix is being field tested (CXO-8919).
  567. X
  568. XThe following procedure can be used (from outside the tue.nl domain) to
  569. Xfind out if your kernel has the bug. From the system under test, do:
  570. X
  571. X    % ftp 131.155.70.100
  572. X
  573. XThis command attempts to make an ftp connection to our anonymous ftp
  574. Xserver (ftp.win.tue.nl).  When the connection has been established, run
  575. Xthe following command from the same system under test, while keeping
  576. Xthe ftp connection open:
  577. X
  578. X    % telnet 131.155.70.100 111
  579. X
  580. XDo not forget the `111' at the end of the command. This telnet command
  581. Xattempts to connect to our portmap process.  The telnet command should
  582. Xfail with:  "host not reachable", or something like that. If your ftp
  583. Xconnection gets messed up, you have the bug. If the telnet command does
  584. Xnot fail, please let me know a.s.a.p.!
  585. X
  586. XFor those who care, the bug is that the BSD kernel code was not careful
  587. Xenough with incoming ICMP UNREACHABLE control messages (it ignored the
  588. Xlocal and remote port numbers). The bug is still present in the BSD
  589. XNET/1 source release (1989) but apparently has been fixed in BSD NET/2
  590. X(1991). You can see it with your own eyes, if you have the courage.
  591. X
  592. X7 - Configuration and installation
  593. X----------------------------------
  594. X
  595. X7.1 - Easy configuration and installation
  596. X-----------------------------------------
  597. X
  598. XThe "easy" recipe requires no changes to existing software or
  599. Xconfiguration files.  Basically, you move the daemons that you want to
  600. Xprotect to a different directory and plug the resulting holes with
  601. Xcopies of the wrapper programs.
  602. X
  603. XIf you don't run Ultrix, you won't need the miscd wrapper program.  The
  604. Xmiscd daemon implements among others the SYSTAT service, which produces
  605. Xthe same output as the the WHO command.
  606. X
  607. XCopy the file Makefile.dist to Makefile, edit the Makefile according to
  608. Xthe instructions at the beginning of that file, and type `make'. 
  609. X
  610. XWhen the `make' succeeds the result is two executables (maybe three in
  611. Xcase of Ultrix). The `try' program can be used to play with host access
  612. Xcontrol tables and is described in a later section.
  613. X
  614. XThe tcpd program can be used to monitor the telnet, finger, ftp, exec,
  615. Xrsh, rlogin, tftp, talk, comsat and other tcp or udp services that have
  616. Xa one-to-one mapping onto executable files.
  617. X
  618. XThe tcpd program can also be used for services that are marked as
  619. Xrpc/udp in the inetd configuration file, but not for rpc/tcp services
  620. Xsuch as rexd.  You probably do not want to run rexd anyway. On most
  621. Xsystems it is even less secure than a wildcard in /etc/hosts.equiv.
  622. X
  623. XThe wrappers are not yet able to deal with TLI-based services.
  624. X
  625. XDecide which services you want to monitor. Move the corresponding
  626. Xvendor-provided daemon programs to the location specified by the
  627. XREAL_DAEMON_DIR constant in the Makefile, and fill the holes with
  628. Xcopies of the tcpd wrapper. That is, one copy of (or link to) the tcpd
  629. Xprogram for each service that you want to monitor. For example, to
  630. Xmonitor the use of your finger service:
  631. X
  632. X    # mkdir REAL_DAEMON_DIR
  633. X    # mv /usr/etc/in.fingerd REAL_DAEMON_DIR
  634. X    # cp tcpd /usr/etc/in.fingerd
  635. X
  636. XThe example applies to SunOS 4. With other UNIX implementations the
  637. Xnetwork daemons live in /usr/libexec or /usr/sbin, or have no "in."
  638. Xprefix to their names, but you get the idea.
  639. X
  640. XUltrix only:  If you want to monitor the SYSTAT service, move the
  641. Xvendor-provided miscd daemon to the location specified by the
  642. XREAL_MISCD macro in the Makefile, and install the miscd wrapper into
  643. Xthe original miscd location.
  644. X
  645. XIn the absence of any access-control tables, the daemon wrappers
  646. Xwill just maintain a record of network connections made to your system.
  647. X
  648. X7.2 - Advanced configuration and installation
  649. X---------------------------------------------
  650. X
  651. XThe advanced recipe leaves your daemon executables alone, but involves
  652. Xsimple modifications to the inetd configuration file.
  653. X
  654. XCopy the file Makefile.dist to Makefile.  In the Makefile, define the
  655. XREAL_DAEMON_DIR macro (if you run Ultrix, the REAL_MISCD macro, too) to
  656. Xreflect the path to your existing network daemons. Don't panic when
  657. Xsome daemons live elsewhere; we'll deal with that later.  Have a look
  658. Xat the other instructions in the Makefile and type `make'.
  659. X
  660. XWhen the `make' succeeds the result is two executables (maybe three in
  661. Xcase of Ultrix). The `try' program can be used to play with host access
  662. Xcontrol tables and is described in a later section.
  663. X
  664. XThe tcpd program can be used to monitor the telnet, finger, ftp, exec,
  665. Xrsh, rlogin, tftp, talk, comsat and other tcp or udp services that have
  666. Xa one-to-one mapping onto executable files.
  667. X
  668. XThe tcpd program can also be used for services that are marked as
  669. Xrpc/udp in the inetd configuration file, but not for rpc/tcp services
  670. Xsuch as rexd.  You probably do not want to run rexd anyway. On most
  671. Xsystems it is even less secure than a wildcard in /etc/hosts.equiv.
  672. X
  673. XThe wrappers are not yet able to deal with TLI-based services.
  674. X
  675. XInstall the tcpd command in a suitable place. Apollo UNIX users will
  676. Xwant to install it under a different name because the name "tcpd" is
  677. Xalready taken; a suitable name for the wrapper program would be
  678. X"frontd".  Then perform the following edits on the inetd configuration
  679. Xfile (usually /etc/inetd.conf or /etc/inet/inetd.conf):
  680. X
  681. X    finger  stream  tcp     nowait  nobody  /usr/etc/in.fingerd     in.fingerd
  682. X
  683. Xbecomes:
  684. X
  685. X    finger  stream  tcp     nowait  nobody  /usr/etc/tcpd           in.fingerd
  686. X
  687. XSend a `kill -HUP' to the inetd process to make the change effective.
  688. X
  689. XThe example applies to SunOS 4. With other UNIX implementations the
  690. Xnetwork daemons live in /usr/libexec or /usr/sbin, the network daemons
  691. Xhave no "in." prefix to their names, or the username field in the inetd
  692. Xconfiguration file may be missing.
  693. X
  694. XWhen the finger service works as expected you can perform similar
  695. Xchanges for other network services. Do not forget the `kill -HUP'.
  696. X
  697. XThe miscd daemon that comes with Ultrix implements several network
  698. Xservices. It decides what to do by looking at its process name. One of
  699. Xthe services is systat, which is a kind of limited finger service.  If
  700. Xyou want to monitor the systat service, install the miscd wrapper in
  701. Xa suitable place and update the inetd configuration file:
  702. X
  703. X    systat  stream  tcp     nowait  /suitable/place/miscd      systatd
  704. X
  705. XUltrix 4.3 allows you to specify a user id under which the daemon will
  706. Xbe executed. This feature is not documented in the manual pages.  Thus,
  707. Xthe example would become:
  708. X
  709. X    systat  stream  tcp     nowait  nobody /suitable/place/miscd    systatd
  710. X
  711. XOlder Ultrix systems still run all their network daemons as root.
  712. X
  713. XIn the absence of any access-control tables, the daemon wrappers
  714. Xwill just maintain a record of network connections made to your system.
  715. X
  716. X7.3 - Daemons with arbitrary path names
  717. X---------------------------------------
  718. X
  719. XThe above tcpd examples work fine with network daemons that live in a
  720. Xcommon directory, but sometimes that is not practical. Having soft
  721. Xlinks all over your file system is not a clean solution, either.
  722. X
  723. XInstead you can specify, in the inetd configuration file, an absolute
  724. Xpath name for the daemon process name.  For example,
  725. X
  726. X    ntalk   dgram   udp     wait    root    /usr/etc/tcpd /usr/local/lib/ntalkd
  727. X
  728. XWhen the daemon process name is an absolute path name, tcpd ignores the
  729. Xvalue of the REAL_DAEMON_DIR constant, and uses the last path component
  730. Xof the daemon process name for logging and for access control.
  731. X
  732. X7.4 - Building and testing the access control rules
  733. X---------------------------------------------------
  734. X
  735. XIn order to support access control the wrappers must be compiled with
  736. Xthe -DHOSTS_ACCESS option. The access control policy is given in the
  737. Xform of two tables (default: /etc/hosts.allow and /etc/hosts.deny).
  738. XAccess control is disabled when there are no access control tables, or
  739. Xwhen the tables are empty.
  740. X
  741. XIf you haven't used the wrappers before I recommend that you first run
  742. Xthem a couple of days without any access control restrictions. The
  743. Xlogfile records should give you an idea of the process names and of the
  744. Xhost names that you will have to build into your access control rules.
  745. X
  746. XThe syntax of the access control rules is documented in the file
  747. Xhosts_access.5, which is in `nroff -man' format. This is a lengthy
  748. Xdocument, and no-one expects you to read it right away from beginning
  749. Xto end.  Instead, after reading the introductory section, skip to the
  750. Xexamples at the end so that you get a general idea of the language.
  751. XThen you can appreciate the detailed reference sections near the
  752. Xbeginning of the document.
  753. X
  754. XThe examples in the hosts_access.5 document show two specific types of
  755. Xaccess control policy:  1) mostly closed (only permitting access from a
  756. Xlimited number of systems) and 2) mostly open (permitting access from
  757. Xeveryone except a limited number of trouble makers). You will have to
  758. Xchoose what model suits your situation best. Implementing a mixed
  759. Xpolicy should not be overly difficult either.
  760. X
  761. XThe `try' command can be used to try out your local access control
  762. Xfiles.  The command syntax is:
  763. X
  764. X    ./try process_name hostname    (e.g.: ./try in.tftpd localhost)
  765. X
  766. X    ./try process_name address    (e.g.: ./try in.tftpd 127.0.0.1)
  767. X
  768. XIn order to find out what process name to use, just use the service and
  769. Xwatch the process name that shows up in the logfile.  Alternatively,
  770. Xyou can look up the name from the inetd configuration file. Coming back
  771. Xto the tftp example in the tutorial section above:
  772. X
  773. X    tftp  dgram  udp  wait  root  /usr/etc/tcpd  in.tftpd -s /tftpboot
  774. X
  775. XThis entry causes the inetd to run the wrapper program (tcpd) with a
  776. Xprocess name `in.tftpd'.  This is the name that the wrapper will use
  777. Xwhen scanning the access control tables. Therefore, `in.tftpd' is the
  778. Xprocess name that should be given to the `try' command. On your system
  779. Xthe actual inetd.conf entry may differ (tftpd instead of in.tftpd, and
  780. Xno `root' field), but you get the idea.
  781. X
  782. XWhen you specify a host name, the `try' program will use both the host
  783. Xname and address. This way you can simulate the most common case where
  784. Xthe wrappers know both the host address and the host name.  The `try'
  785. Xprogram will iterate over all addresses that it can find for the given
  786. Xhost name.
  787. X
  788. XWhen you specify a host address instead of a host name, the `try'
  789. Xprogram will pretend that the host name is unknown, so that you can
  790. Xsimulate what happens when the wrapper is unable to look up the remote
  791. Xhost name.
  792. X
  793. XSerious errors in the configuration file syntax will be reported via
  794. Xthe syslog daemon.  Run a `tail -f' on the logfile while playing with
  795. Xthe `try' command. The tutorial section at the beginning of this file
  796. Xdescribes where to look for your logfile.
  797. X
  798. X7.5 - Other applications
  799. X------------------------
  800. X
  801. XThe access control routines can easily be integrated with other
  802. Xprograms.  The hosts_access.3 manual page (`nroff -man' format)
  803. Xdescribes the external interface of the libwrap.a library.
  804. X
  805. XThe tcpd wrapper can even be used to control access to the smtp port.
  806. XIn that case, sendmail should not be run as a stand-alone daemon, but
  807. Xit should be registered in the inetd configuration file. For example:
  808. X
  809. X    smtp    stream  tcp     nowait  root    /usr/etc/tcpd /usr/lib/sendmail -bs
  810. X
  811. XYou will periodically want to run sendmail to process queued-up
  812. Xmessages. A crontab entry like:
  813. X
  814. X    0,15,30,45 * * * * /usr/lib/sendmail -q
  815. X
  816. Xshould take care of that. When you are going to "protect" your sendmail
  817. Xdaemon this way, you should realize that there are many "unprotected"
  818. Xsendmail daemons all over the network that can still be abused.
  819. X
  820. X8 - Acknowledgements
  821. X--------------------
  822. X
  823. XMany people contributed to the evolution of the programs, by asking
  824. Xinspiring questions, by suggesting features or bugfixes, or by
  825. Xsubmitting source code.  Nevertheless, all mistakes and bugs in the
  826. Xwrappers are my own.
  827. X
  828. XThanks to Brendan Kehoe (brendan@cs.widener.edu), Heimir Sverrisson
  829. X(heimir@hafro.is) and Dan Bernstein (brnstnd@kramden.acf.nyu.edu) for
  830. Xfeedback on an early release of this product.  The host name/address
  831. Xcheck was suggested by John Kimball (jkimball@src.honeywell.com).
  832. XApollo's UNIX environment has some peculiar quirks: Willem-Jan Withagen
  833. X(wjw@eb.ele.tue.nl), Pieter Schoenmakers (tiggr@es.ele.tue.nl) and
  834. XCharles S. Fuller (fuller@wccs.psc.edu) provided assistance.  Hal R.
  835. XBrand (BRAND@addvax.llnl.gov) told me how to get the remote IP address
  836. Xin case of datagram-oriented services, and suggested the optional shell
  837. Xcommand feature.  Shabbir Safdar (shabby@mentor.cc.purdue.edu) provided
  838. Xa first version of a much-needed manual page.  Granville Boman Goza, IV
  839. X(gbg@sei.cmu.edu) suggested to use the remote IP address even when the
  840. Xhost name is available.  Casper H.S. Dik (casper@fwi.uva.nl) provided
  841. Xadditional insight into DNS spoofing techniques.  The bogus daemon
  842. Xfeature was inspired by code from Andrew Macpherson (BNR Europe Ltd).
  843. XSteve Bellovin (smb@research.att.com) confirmed some of my suspicions
  844. Xabout the darker sides of TCP/IP insecurity.
  845. X
  846. XIn no particular order, Howard Chu (hyc@hanauma.jpl.nasa.gov), John P.
  847. XRouillard (rouilj@cs.umb.edu), Darren Reed (avalon@coombs.anu.edu.au),
  848. XIcarus Sparry (I.Sparry@gdr.bath.ac.uk), Scott Schwartz (schwartz@
  849. Xcs.psu.edu), John A. Kunze (jak@violet.berkeley.edu), Daniel Len
  850. XSchales (dan@engr.latech.edu), Chris Turbeville <turbo@cse.uta.edu>,
  851. XPaul Kranenburg <pk@cs.few.eur.nl>, and many, many others provided
  852. Xfixes, code fragments, or other improvements to the wrappers.
  853. X
  854. X    Wietse Venema (wietse@wzv.win.tue.nl)
  855. X    Department of Mathematics and Computing Science
  856. X    Eindhoven University of Technology
  857. X    P.O. Box 513
  858. X    5600 MB Eindhoven
  859. X    The Netherlands
  860. END_OF_README
  861. if test 34888 -ne `wc -c <README`; then
  862.     echo shar: \"README\" unpacked with wrong size!
  863. fi
  864. # end of overwriting check
  865. fi
  866. if test -f miscd.c -a "${1}" != "-c" ; then 
  867.   echo shar: Will not over-write existing file \"miscd.c\"
  868. else
  869. echo shar: Extracting \"miscd.c\" \(2602 characters\)
  870. sed "s/^X//" >miscd.c <<'END_OF_miscd.c'
  871. X /*
  872. X  * Front end to the ULTRIX miscd service. The front end logs the remote host
  873. X  * name and then invokes the real miscd daemon. Install as "/usr/etc/miscd",
  874. X  * after moving the real miscd daemon to the "/usr/etc/..." directory.
  875. X  * Connections and diagnostics are logged through syslog(3).
  876. X  * 
  877. X  * The Ultrix miscd program implements (among others) the systat service, which
  878. X  * pipes the output from who(1) to stdout. This information is potentially
  879. X  * useful to systems crackers.
  880. X  * 
  881. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  882. X  */
  883. X
  884. X#ifndef lint
  885. Xstatic char sccsid[] = "@(#) miscd.c 1.4 93/03/07 22:47:28";
  886. X#endif
  887. X
  888. X/* System libraries. */
  889. X
  890. X#include <sys/types.h>
  891. X#include <sys/param.h>
  892. X#include <sys/stat.h>
  893. X#include <stdio.h>
  894. X#include <syslog.h>
  895. X
  896. X/* Local stuff. */
  897. X
  898. X#include "patchlevel.h"
  899. X#include "log_tcp.h"
  900. X
  901. X/* The following specifies where the vendor-provided daemon should go. */
  902. X
  903. X#ifndef REAL_MISCD
  904. X#define REAL_MISCD    "/usr/etc/.../miscd"
  905. X#endif
  906. X
  907. Xint     log_severity = SEVERITY;    /* run-time adjustable */
  908. X
  909. Xmain(argc, argv)
  910. Xint     argc;
  911. Xchar  **argv;
  912. X{
  913. X    struct from_host from;
  914. X    int     from_stat;
  915. X
  916. X    /* Attempt to prevent the creation of world-writable files. */
  917. X
  918. X#ifdef DAEMON_UMASK
  919. X    umask(DAEMON_UMASK);
  920. X#endif
  921. X
  922. X    /*
  923. X     * Open a channel to the syslog daemon. Older versions of openlog()
  924. X     * require only two arguments.
  925. X     */
  926. X
  927. X#ifdef LOG_MAIL
  928. X    (void) openlog(argv[0], LOG_PID, FACILITY);
  929. X#else
  930. X    (void) openlog(argv[0], LOG_PID);
  931. X#endif
  932. X
  933. X    /*
  934. X     * Find out and verify the remote host name. Sites concerned with
  935. X     * security may choose to refuse connections from hosts that pretend to
  936. X     * have someone elses host name.
  937. X     */
  938. X
  939. X    from_stat = fromhost(&from);
  940. X#ifdef PARANOID
  941. X    if (from_stat == -1)
  942. X    refuse(&from);
  943. X#endif
  944. X
  945. X    /*
  946. X     * The BSD rlogin and rsh daemons that came out after 4.3 BSD disallow
  947. X     * socket options at the IP level. They do so for a good reason. Let's
  948. X     * follow their example.
  949. X     */
  950. X
  951. X#ifdef KILL_IP_OPTIONS
  952. X    fix_options(&from);
  953. X#endif
  954. X
  955. X    /*
  956. X     * Check whether this host can access the service in argv[0]. The
  957. X     * access-control code invokes optional shell commands as specified in
  958. X     * the access-control tables.
  959. X     */
  960. X
  961. X#ifdef HOSTS_ACCESS
  962. X    if (!hosts_access(argv[0], &from))
  963. X    refuse(&from);
  964. X#endif
  965. X
  966. X    /* Report remote client and invoke the real daemon program. */
  967. X
  968. X    syslog(log_severity, "connect from %s", hosts_info(&from));
  969. X    (void) execv(REAL_MISCD, argv);
  970. X    syslog(LOG_ERR, "%s: %m", REAL_MISCD);
  971. X    clean_exit(&from);
  972. X    /* NOTREACHED */
  973. X}
  974. END_OF_miscd.c
  975. if test 2602 -ne `wc -c <miscd.c`; then
  976.     echo shar: \"miscd.c\" unpacked with wrong size!
  977. fi
  978. # end of overwriting check
  979. fi
  980. if test -f tcpd.c -a "${1}" != "-c" ; then 
  981.   echo shar: Will not over-write existing file \"tcpd.c\"
  982. else
  983. echo shar: Extracting \"tcpd.c\" \(2995 characters\)
  984. sed "s/^X//" >tcpd.c <<'END_OF_tcpd.c'
  985. X /*
  986. X  * General front end for stream and datagram IP services. This program logs
  987. X  * the remote host name and then invokes the real daemon. For example,
  988. X  * install as /usr/etc/{tftpd,fingerd,telnetd,ftpd,rlogind,rshd,rexecd},
  989. X  * after saving the real daemons in the directory "/usr/etc/...". This
  990. X  * arrangement requires that the network daemons are started by inetd or
  991. X  * something similar. Connections and diagnostics are logged through
  992. X  * syslog(3).
  993. X  * 
  994. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  995. X  */
  996. X
  997. X#ifndef lint
  998. Xstatic char sccsid[] = "@(#) tcpd.c 1.4 93/03/07 22:47:32";
  999. X#endif
  1000. X
  1001. X/* System libraries. */
  1002. X
  1003. X#include <sys/types.h>
  1004. X#include <sys/param.h>
  1005. X#include <sys/stat.h>
  1006. X#include <stdio.h>
  1007. X#include <syslog.h>
  1008. X
  1009. Xextern char *strrchr();
  1010. Xextern char *strcpy();
  1011. X
  1012. X#ifndef MAXPATHNAMELEN
  1013. X#define MAXPATHNAMELEN    BUFSIZ
  1014. X#endif
  1015. X
  1016. X/* Local stuff. */
  1017. X
  1018. X#include "patchlevel.h"
  1019. X#include "log_tcp.h"
  1020. X
  1021. X/* The following specifies where the vendor-provided daemons should go. */
  1022. X
  1023. X#ifndef REAL_DAEMON_DIR
  1024. X#define REAL_DAEMON_DIR    "/usr/etc/..."
  1025. X#endif
  1026. X
  1027. Xint     log_severity = SEVERITY;    /* run-time adjustable */
  1028. X
  1029. Xmain(argc, argv)
  1030. Xint     argc;
  1031. Xchar  **argv;
  1032. X{
  1033. X    struct from_host from;
  1034. X    int     from_stat;
  1035. X    char    path[MAXPATHNAMELEN];
  1036. X
  1037. X    /* Attempt to prevent the creation of world-writable files. */
  1038. X
  1039. X#ifdef DAEMON_UMASK
  1040. X    umask(DAEMON_UMASK);
  1041. X#endif
  1042. X
  1043. X    /*
  1044. X     * If argv[0] is an absolute path name, ignore REAL_DAEMON_DIR, and strip
  1045. X     * argv[0] to its basename.
  1046. X     */
  1047. X
  1048. X    if (argv[0][0] == '/') {
  1049. X    strcpy(path, argv[0]);
  1050. X    argv[0] = strrchr(argv[0], '/') + 1;
  1051. X    } else {
  1052. X    sprintf(path, "%s/%s", REAL_DAEMON_DIR, argv[0]);
  1053. X    }
  1054. X
  1055. X    /*
  1056. X     * Open a channel to the syslog daemon. Older versions of openlog()
  1057. X     * require only two arguments.
  1058. X     */
  1059. X
  1060. X#ifdef LOG_MAIL
  1061. X    (void) openlog(argv[0], LOG_PID, FACILITY);
  1062. X#else
  1063. X    (void) openlog(argv[0], LOG_PID);
  1064. X#endif
  1065. X
  1066. X    /*
  1067. X     * Find out and verify the remote host name. Sites concerned with
  1068. X     * security may choose to refuse connections from hosts that pretend to
  1069. X     * have someone elses host name.
  1070. X     */
  1071. X
  1072. X    from_stat = fromhost(&from);
  1073. X#ifdef PARANOID
  1074. X    if (from_stat == -1)
  1075. X    refuse(&from);
  1076. X#endif
  1077. X
  1078. X    /*
  1079. X     * The BSD rlogin and rsh daemons that came out after 4.3 BSD disallow
  1080. X     * socket options at the IP level. They do so for a good reason. Let's
  1081. X     * follow their example.
  1082. X     */
  1083. X
  1084. X#ifdef KILL_IP_OPTIONS
  1085. X    fix_options(&from);
  1086. X#endif
  1087. X
  1088. X    /*
  1089. X     * Check whether this host can access the service in argv[0]. The
  1090. X     * access-control code invokes optional shell commands as specified in
  1091. X     * the access-control tables.
  1092. X     */
  1093. X
  1094. X#ifdef HOSTS_ACCESS
  1095. X    if (!hosts_access(argv[0], &from))
  1096. X    refuse(&from);
  1097. X#endif
  1098. X
  1099. X    /* Report remote client and invoke the real daemon program. */
  1100. X
  1101. X    syslog(log_severity, "connect from %s", hosts_info(&from));
  1102. X    (void) execv(path, argv);
  1103. X    syslog(LOG_ERR, "%s: %m", path);
  1104. X    clean_exit(&from);
  1105. X    /* NOTREACHED */
  1106. X}
  1107. END_OF_tcpd.c
  1108. if test 2995 -ne `wc -c <tcpd.c`; then
  1109.     echo shar: \"tcpd.c\" unpacked with wrong size!
  1110. fi
  1111. # end of overwriting check
  1112. fi
  1113. if test -f fromhost.c -a "${1}" != "-c" ; then 
  1114.   echo shar: Will not over-write existing file \"fromhost.c\"
  1115. else
  1116. echo shar: Extracting \"fromhost.c\" \(8144 characters\)
  1117. sed "s/^X//" >fromhost.c <<'END_OF_fromhost.c'
  1118. X /*
  1119. X  * fromhost() determines the type of connection (datagram, stream), the name
  1120. X  * and address of the host at the other end of standard input, and the
  1121. X  * remote user name (if RFC 931 lookups are enabled). A host name of "stdin"
  1122. X  * is returned if the program is run from a tty. The value "unknown" is
  1123. X  * returned as a placeholder for information that could not be looked up.
  1124. X  * All results are in static memory.
  1125. X  * 
  1126. X  * The return status is (-1) if the remote host pretends to have someone elses
  1127. X  * host name, otherwise a zero status is returned.
  1128. X  * 
  1129. X  * Diagnostics are reported through syslog(3).
  1130. X  * 
  1131. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  1132. X  */
  1133. X
  1134. X#ifndef lint
  1135. Xstatic char sccsid[] = "@(#) fromhost.c 1.7 93/03/07 22:47:34";
  1136. X#endif
  1137. X
  1138. X/* System libraries. */
  1139. X
  1140. X#include <sys/types.h>
  1141. X#include <sys/param.h>
  1142. X#include <sys/socket.h>
  1143. X#include <netinet/in.h>
  1144. X#include <netdb.h>
  1145. X#include <stdio.h>
  1146. X#include <syslog.h>
  1147. X#include <errno.h>
  1148. X
  1149. Xextern char *inet_ntoa();
  1150. Xextern char *strncpy();
  1151. Xextern char *strcpy();
  1152. X
  1153. X/* In case not defined in <sys/param.h>. */
  1154. X
  1155. X#ifndef MAXHOSTNAMELEN
  1156. X#define MAXHOSTNAMELEN    1024        /* string with host name */
  1157. X#endif
  1158. X
  1159. X/* Local stuff. */
  1160. X
  1161. X#include "log_tcp.h"
  1162. X
  1163. X/* Forward declarations. */
  1164. X
  1165. Xstatic int matchname();
  1166. X
  1167. X/* The following are to be used in assignment context, not in comparisons. */
  1168. X
  1169. X#define    GOOD    1
  1170. X#define    BAD    0
  1171. X
  1172. X/* Initially, we know nothing about the origin of the connection. */
  1173. X
  1174. Xstatic struct from_host from_unknown = {
  1175. X    0,                    /* connected/unconnected */
  1176. X    FROM_UNKNOWN,            /* remote host name */
  1177. X    FROM_UNKNOWN,            /* remote host address */
  1178. X    "",                    /* remote user name */
  1179. X};
  1180. X
  1181. X /*
  1182. X  * With early SunOS 5 versions, recvfrom() does not completely fill in the
  1183. X  * source address structure when doing a non-destructive read. The following
  1184. X  * code works around the problem. It does no harm on "normal" systems.
  1185. X  */
  1186. X
  1187. X#ifdef RECVFROM_BUG
  1188. X
  1189. Xstatic int fix_recvfrom(sock, buf, buflen, flags, from, fromlen)
  1190. Xint     sock;
  1191. Xchar   *buf;
  1192. Xint     buflen;
  1193. Xint     flags;
  1194. Xstruct sockaddr *from;
  1195. Xint     *fromlen;
  1196. X{
  1197. X    int     ret;
  1198. X
  1199. X    /* Assume that both ends of a socket belong to the same address family. */
  1200. X
  1201. X    if ((ret = recvfrom(sock, buf, buflen, flags, from, fromlen)) >= 0) {
  1202. X    if (from->sa_family == 0) {
  1203. X        struct sockaddr my_addr;
  1204. X        int     my_addr_len = sizeof(my_addr);
  1205. X
  1206. X        if (getsockname(0, &my_addr, &my_addr_len)) {
  1207. X        syslog(LOG_ERR, "getsockname: %m");
  1208. X        } else {
  1209. X        from->sa_family = my_addr.sa_family;
  1210. X        }
  1211. X    }
  1212. X    }
  1213. X    return (ret);
  1214. X}
  1215. X
  1216. X#define recvfrom fix_recvfrom
  1217. X#endif
  1218. X
  1219. X /*
  1220. X  * The Apollo SR10.3 and some SYSV4 getpeername(2) versions do not return an
  1221. X  * error in case of a datagram-oriented socket. Instead, they claim that all
  1222. X  * UDP requests come from address 0.0.0.0. The following code works around
  1223. X  * the problem. It does no harm on "normal" systems.
  1224. X  */
  1225. X
  1226. X#ifdef GETPEERNAME_BUG
  1227. X
  1228. Xstatic int fix_getpeername(sock, sa, len)
  1229. Xint     sock;
  1230. Xstruct sockaddr *sa;
  1231. Xint    *len;
  1232. X{
  1233. X    int     ret;
  1234. X    struct sockaddr_in *sin = (struct sockaddr_in *) sa;
  1235. X
  1236. X    if ((ret = getpeername(sock, sa, len)) >= 0
  1237. X    && sa->sa_family == AF_INET
  1238. X    && sin->sin_addr.s_addr == 0) {
  1239. X    errno = ENOTCONN;
  1240. X    return (-1);
  1241. X    } else {
  1242. X    return (ret);
  1243. X    }
  1244. X}
  1245. X
  1246. X#define    getpeername    fix_getpeername
  1247. X#endif
  1248. X
  1249. X/* fromhost - find out what is at the other end of standard input */
  1250. X
  1251. Xint     fromhost(f)
  1252. Xstruct from_host *f;
  1253. X{
  1254. X    static struct sockaddr sa;
  1255. X    struct sockaddr_in *sin = (struct sockaddr_in *) (&sa);
  1256. X    struct hostent *hp;
  1257. X    int     length = sizeof(sa);
  1258. X    char    buf[BUFSIZ];
  1259. X    static char addr_buf[FROM_ADDRLEN];
  1260. X    static char name_buf[MAXHOSTNAMELEN];
  1261. X
  1262. X    /*
  1263. X     * There are so many results and so many early returns that it seems
  1264. X     * safest to first initialize all results to UNKNOWN.
  1265. X     */
  1266. X
  1267. X    *f = from_unknown;
  1268. X
  1269. X    /*
  1270. X     * Look up the remote host address. Hal R. Brand <BRAND@addvax.llnl.gov>
  1271. X     * suggested how to get the remote host info in case of UDP connections:
  1272. X     * peek at the first message without actually looking at its contents.
  1273. X     */
  1274. X
  1275. X    if (getpeername(0, &sa, &length) >= 0) {    /* assume TCP request */
  1276. X    f->sock_type = FROM_CONNECTED;
  1277. X    } else {
  1278. X    switch (errno) {
  1279. X    default:
  1280. X        if (isatty(0))            /* stdin is not a socket */
  1281. X        f->name = "stdin";
  1282. X        else
  1283. X        syslog(LOG_ERR, "getpeername: %m");    /* other, punt */
  1284. X        return (0);
  1285. X    case ENOTCONN:                /* assume UDP request */
  1286. X        length = sizeof(sa);
  1287. X        if (recvfrom(0, buf, sizeof(buf), MSG_PEEK, &sa, &length) < 0) {
  1288. X        syslog(LOG_ERR, "recvfrom: %m");
  1289. X        return (0);
  1290. X        }
  1291. X#ifdef really_paranoid
  1292. X        memset(buf, 0 sizeof(buf));
  1293. X#endif
  1294. X        f->sock_type = FROM_UNCONNECTED;
  1295. X        break;
  1296. X    }
  1297. X    }
  1298. X
  1299. X    /*
  1300. X     * At present, we can only deal with the AF_INET address family. Some
  1301. X     * implementations of System V religion never fill in the address family
  1302. X     * field in case of UDP connections. If that happens, you may want to
  1303. X     * take the chance and assume that we're dealing with TCP/IP anyway.
  1304. X     */
  1305. X
  1306. X#ifdef ADDRESS_FAMILY_BUG
  1307. X    if (sa.sa_family == 0)
  1308. X    sa.sa_family = AF_INET;
  1309. X#endif
  1310. X    if (sa.sa_family != AF_INET) {
  1311. X    syslog(LOG_ERR, "unexpected address family %ld", (long) sa.sa_family);
  1312. X    return (0);
  1313. X    }
  1314. X    /* Save the host address. A later inet_ntoa() call may clobber it. */
  1315. X
  1316. X    f->sin = sin;
  1317. X    f->addr = strcpy(addr_buf, inet_ntoa(sin->sin_addr));
  1318. X
  1319. X    /* Look up the remote user name. Does not work for UDP services. */
  1320. X
  1321. X#if defined(RFC931) && !defined(USER_AT_HOST) && !defined(RFC931_OPTION)
  1322. X    if (f->sock_type == FROM_CONNECTED)
  1323. X    f->user = rfc931_name(sin);
  1324. X#endif
  1325. X
  1326. X    /* Look up the remote host name. */
  1327. X
  1328. X    if ((hp = gethostbyaddr((char *) &sin->sin_addr,
  1329. X                sizeof(sin->sin_addr),
  1330. X                AF_INET)) == 0) {
  1331. X    return (0);
  1332. X    }
  1333. X    /* Save the host name. A later gethostbyxxx() call may clobber it. */
  1334. X
  1335. X    f->name = strncpy(name_buf, hp->h_name, sizeof(name_buf) - 1);
  1336. X    name_buf[sizeof(name_buf) - 1] = 0;
  1337. X
  1338. X    /*
  1339. X     * Verify that the host name does not belong to someone else. If host
  1340. X     * name verification fails, pretend that the host name lookup failed.
  1341. X     */
  1342. X
  1343. X    if (matchname(f->name, sin->sin_addr)) {
  1344. X    return (0);
  1345. X    } else {
  1346. X    f->name = FROM_UNKNOWN;
  1347. X    return (-1);                /* verification failed */
  1348. X    }
  1349. X}
  1350. X
  1351. X/* matchname - determine if host name matches IP address */
  1352. X
  1353. Xstatic int matchname(remotehost, addr)
  1354. Xchar   *remotehost;
  1355. Xstruct in_addr addr;
  1356. X{
  1357. X    struct hostent *hp;
  1358. X    int     i;
  1359. X
  1360. X    if ((hp = gethostbyname(remotehost)) == 0) {
  1361. X
  1362. X    /*
  1363. X     * Unable to verify that the host name matches the address. This may
  1364. X     * be a transient problem or a botched name server setup. We decide
  1365. X     * to play safe.
  1366. X     */
  1367. X
  1368. X    syslog(LOG_ERR, "gethostbyname(%s): lookup failure", remotehost);
  1369. X    return (BAD);
  1370. X
  1371. X    } else {
  1372. X
  1373. X    /*
  1374. X     * Make sure that gethostbyname() returns the "correct" host name.
  1375. X     * Unfortunately, gethostbyname("localhost") sometimes yields
  1376. X     * "localhost.domain". Since the latter host name comes from the
  1377. X     * local DNS, we just have to trust it (all bets are off if the local
  1378. X     * DNS is perverted). We always check the address list, though.
  1379. X     */
  1380. X
  1381. X    if (strcasecmp(remotehost, hp->h_name)
  1382. X        && strcasecmp(remotehost, "localhost")) {
  1383. X        syslog(LOG_ERR, "host name/name mismatch: %s != %s",
  1384. X           remotehost, hp->h_name);
  1385. X        return (BAD);
  1386. X    }
  1387. X    /* Look up the host address in the address list we just got. */
  1388. X
  1389. X    for (i = 0; hp->h_addr_list[i]; i++) {
  1390. X        if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
  1391. X        return (GOOD);
  1392. X    }
  1393. X
  1394. X    /*
  1395. X     * The host name does not map to the original host address. Perhaps
  1396. X     * someone has compromised a name server. More likely someone botched
  1397. X     * it, but that could be dangerous, too.
  1398. X     */
  1399. X
  1400. X    syslog(LOG_ERR, "host name/address mismatch: %s != %s",
  1401. X           inet_ntoa(addr), hp->h_name);
  1402. X    return (BAD);
  1403. X    }
  1404. X}
  1405. X
  1406. X#ifdef TEST
  1407. X
  1408. X/* Code for stand-alone testing. */
  1409. X
  1410. Xmain(argc, argv)
  1411. Xint     argc;
  1412. Xchar  **argv;
  1413. X{
  1414. X    struct from_host from;
  1415. X
  1416. X#ifdef LOG_MAIL
  1417. X    (void) openlog(argv[0], LOG_PID, FACILITY);
  1418. X#else
  1419. X    (void) openlog(argv[0], LOG_PID);
  1420. X#endif
  1421. X    (void) fromhost(&from);
  1422. X    printf("%s\n", hosts_info(&from));
  1423. X    return (0);
  1424. X}
  1425. X
  1426. X#endif
  1427. END_OF_fromhost.c
  1428. if test 8144 -ne `wc -c <fromhost.c`; then
  1429.     echo shar: \"fromhost.c\" unpacked with wrong size!
  1430. fi
  1431. # end of overwriting check
  1432. fi
  1433. if test -f hosts_access.c -a "${1}" != "-c" ; then 
  1434.   echo shar: Will not over-write existing file \"hosts_access.c\"
  1435. else
  1436. echo shar: Extracting \"hosts_access.c\" \(11173 characters\)
  1437. sed "s/^X//" >hosts_access.c <<'END_OF_hosts_access.c'
  1438. X /*
  1439. X  * This module implements a simple access control language that is based on
  1440. X  * host (or domain) names, netgroup, internet addresses (or network numbers)
  1441. X  * and daemon process names. When a match is found an optional shell command
  1442. X  * is executed and the search is terminated.
  1443. X  * 
  1444. X  * Diagnostics are reported through syslog(3).
  1445. X  * 
  1446. X  * Compile with -DNETGROUP if your library provides support for netgroups.
  1447. X  * 
  1448. X  * Compile with -DUSER_AT_HOST for rule-driven username lookups.
  1449. X  * 
  1450. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  1451. X  */
  1452. X
  1453. X#ifndef lint
  1454. Xstatic char sccsid[] = "@(#) hosts_access.c 1.10 93/03/07 22:47:36";
  1455. X#endif
  1456. X
  1457. X /* System libraries. */
  1458. X
  1459. X#include <sys/types.h>
  1460. X#include <sys/param.h>
  1461. X#include <netinet/in.h>
  1462. X#include <arpa/inet.h>
  1463. X#include <stdio.h>
  1464. X#include <syslog.h>
  1465. X#include <ctype.h>
  1466. X#include <errno.h>
  1467. X
  1468. Xextern char *fgets();
  1469. Xextern char *strchr();
  1470. Xextern char *strtok();
  1471. X
  1472. X#ifndef    INADDR_NONE
  1473. X#define    INADDR_NONE    (-1)        /* XXX should be 0xffffffff */
  1474. X#endif
  1475. X
  1476. X/* Local stuff. */
  1477. X
  1478. X#include "log_tcp.h"
  1479. X
  1480. X#ifdef INET_ADDR_BUG
  1481. X#include "inet_addr_fix"
  1482. X#endif
  1483. X
  1484. X/* Delimiters for lists of daemons or clients. */
  1485. X
  1486. Xstatic char sep[] = ", \t";
  1487. X
  1488. X/* Constants to be used in assignments only, not in comparisons... */
  1489. X
  1490. X#define    YES        1
  1491. X#define    NO        0
  1492. X#define    FAIL        (-1)
  1493. X
  1494. X/* Forward declarations. */
  1495. X
  1496. Xstatic int table_match();
  1497. Xstatic int list_match();
  1498. Xstatic int client_match();
  1499. Xstatic int string_match();
  1500. Xstatic int masked_match();
  1501. Xstatic char *xgets();
  1502. X
  1503. X/* The user@host access control. Trivial to add but complicates use. */
  1504. X
  1505. X#ifdef USER_AT_HOST
  1506. Xstatic int userhost_match();
  1507. X#define CLIENT_MATCH userhost_match
  1508. X#else
  1509. X#define CLIENT_MATCH client_match
  1510. X#endif
  1511. X
  1512. X/* Size of logical line buffer. */
  1513. X
  1514. X#define    BUFLEN 2048
  1515. X
  1516. X/* hosts_access - host access control facility */
  1517. X
  1518. Xint     hosts_access(daemon, client)
  1519. Xchar   *daemon;
  1520. Xstruct from_host *client;        /* host or user name may be empty */
  1521. X{
  1522. X
  1523. X    /*
  1524. X     * If the (daemon, client) pair is matched by an entry in the file
  1525. X     * /etc/hosts.allow, access is granted. Otherwise, if the (daemon,
  1526. X     * client) pair is matched by an entry in the file /etc/hosts.deny,
  1527. X     * access is denied. Otherwise, access is granted. A non-existent
  1528. X     * access-control file is treated as an empty file.
  1529. X     */
  1530. X
  1531. X    if (table_match(HOSTS_ALLOW, daemon, client))
  1532. X    return (YES);
  1533. X    if (table_match(HOSTS_DENY, daemon, client))
  1534. X    return (NO);
  1535. X    return (YES);
  1536. X}
  1537. X
  1538. X/* table_match - match table entries with (daemon, client) pair */
  1539. X
  1540. Xstatic int table_match(table, daemon, client)
  1541. Xchar   *table;
  1542. Xchar   *daemon;
  1543. Xstruct from_host *client;        /* host or user name may be empty */
  1544. X{
  1545. X    FILE   *fp;
  1546. X    char    sv_list[BUFLEN];        /* becomes list of daemons */
  1547. X    char   *cl_list;            /* becomes list of clients */
  1548. X    char   *sh_cmd;            /* becomes optional shell command */
  1549. X    int     match;
  1550. X    int     end;
  1551. X
  1552. X    /* The following variables should always be tested together. */
  1553. X
  1554. X    int     sv_match = NO;        /* daemon matched */
  1555. X    int     cl_match = NO;        /* client matced */
  1556. X
  1557. X    /*
  1558. X     * Process the table one logical line at a time. Lines that begin with a
  1559. X     * '#' character are ignored. Non-comment lines are broken at the ':'
  1560. X     * character (we complain if there is none). The first field is matched
  1561. X     * against the daemon process name (argv[0]), the second field against
  1562. X     * the host name or address. A non-existing table is treated as if it
  1563. X     * were an empty table. The search terminates at the first matching rule.
  1564. X     * When a match is found an optional shell command is executed.
  1565. X     */
  1566. X
  1567. X    if (fp = fopen(table, "r")) {
  1568. X    while (!(sv_match && cl_match) && xgets(sv_list, sizeof(sv_list), fp)) {
  1569. X        if (sv_list[end = strlen(sv_list) - 1] != '\n') {
  1570. X        syslog(LOG_ERR, "%s: missing newline or line too long", table);
  1571. X        continue;
  1572. X        }
  1573. X        if (sv_list[0] == '#')        /* skip comments */
  1574. X        continue;
  1575. X        while (end > 0 && isspace(sv_list[end - 1]))
  1576. X         end--;
  1577. X        sv_list[end] = '\0';        /* strip trailing whitespace */
  1578. X        if (sv_list[0] == 0)        /* skip blank lines */
  1579. X        continue;
  1580. X        if ((cl_list = strchr(sv_list, ':')) == 0) {
  1581. X        syslog(LOG_ERR, "%s: malformed entry: \"%s\"", table, sv_list);
  1582. X        continue;
  1583. X        }
  1584. X        *cl_list++ = '\0';            /* split 1st and 2nd fields */
  1585. X        if ((sh_cmd = strchr(cl_list, ':')) != 0)
  1586. X        *sh_cmd++ = '\0';        /* split 2nd and 3rd fields */
  1587. X        if ((sv_match = list_match(sv_list, daemon, string_match)))
  1588. X        cl_match = list_match(cl_list, (char *) client, CLIENT_MATCH);
  1589. X    }
  1590. X    (void) fclose(fp);
  1591. X    } else if (errno != ENOENT) {
  1592. X    syslog(LOG_ERR, "cannot open %s: %m", table);
  1593. X    }
  1594. X    match = (sv_match == YES && cl_match == YES);
  1595. X    if (match && sh_cmd)
  1596. X    OPTIONS_STYLE(sh_cmd, daemon, client);
  1597. X    return (match);
  1598. X}
  1599. X
  1600. X/* list_match - match an item against a list of tokens with exceptions */
  1601. X
  1602. Xstatic int list_match(list, item, match_fn)
  1603. Xchar   *list;
  1604. Xchar   *item;
  1605. Xint   (*match_fn) ();
  1606. X{
  1607. X    char   *tok;
  1608. X    int     match = NO;
  1609. X
  1610. X    /*
  1611. X     * Process tokens one at a time. We have exhausted all possible matches
  1612. X     * when we reach an "EXCEPT" token or the end of the list. If we do find
  1613. X     * a match, look for an "EXCEPT" list and recurse to determine whether
  1614. X     * the match is affected by any exceptions.
  1615. X     */
  1616. X
  1617. X    for (tok = strtok(list, sep); tok != 0; tok = strtok((char *) 0, sep)) {
  1618. X    if (strcasecmp(tok, "EXCEPT") == 0)    /* EXCEPT: give up */
  1619. X        break;
  1620. X    if (match = (*match_fn) (tok, item))    /* YES or FAIL */
  1621. X        break;
  1622. X    }
  1623. X    /* Process exceptions to YES or FAIL matches. */
  1624. X
  1625. X    if (match != NO) {
  1626. X    while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT"))
  1627. X         /* VOID */ ;
  1628. X    if (tok == 0 || list_match((char *) 0, item, match_fn) == NO)
  1629. X        return (match);
  1630. X    }
  1631. X    return (NO);
  1632. X}
  1633. X
  1634. X/* client_match - match host name and address against token */
  1635. X
  1636. Xstatic int client_match(tok, item)
  1637. Xchar   *tok;
  1638. Xchar   *item;
  1639. X{
  1640. X    struct from_host *client = (struct from_host *) item;
  1641. X    int     match;
  1642. X
  1643. X    /*
  1644. X     * Try to match the address first. If that fails, try to match the host
  1645. X     * name if available.
  1646. X     */
  1647. X
  1648. X    if ((match = string_match(tok, client->addr)) == 0)
  1649. X    if (client->name[0] != 0)
  1650. X        match = string_match(tok, client->name);
  1651. X    return (match);
  1652. X}
  1653. X
  1654. X#ifdef USER_AT_HOST
  1655. X
  1656. X/* userhost_match - do user@host access control */
  1657. X
  1658. Xstatic int userhost_match(tok, item)
  1659. Xchar   *tok;
  1660. Xchar   *item;
  1661. X{
  1662. X    struct from_host *client = (struct from_host *) item;
  1663. X    int     match = NO;
  1664. X    char   *at;
  1665. X    int     host_match;
  1666. X    int     user_match;
  1667. X
  1668. X    /*
  1669. X     * Warning: experimental code, enabled only when USER_AT_HOST is defined.
  1670. X     * 
  1671. X     * Basically, you specify user_pattern@host_pattern where remote username
  1672. X     * lookups are desired, and plain host_pattern for all other cases. The
  1673. X     * syntax of user name patterns is the same as for hosts or daemons, but
  1674. X     * ALL is probably the only user_pattern that makes sense.
  1675. X     * 
  1676. X     * In case of UDP connections, the result of username lookup will always be
  1677. X     * "unknown".
  1678. X     * 
  1679. X     * Return FAIL if we match a pattern of the form user@FAIL or FAIL@host:
  1680. X     * FAIL, like NO, is transitive. According to some people, such patterns
  1681. X     * should be taken out and shot. Good news: FAIL is on its way out.
  1682. X     */
  1683. X
  1684. X    if (at = strchr(tok + 1, '@')) {        /* user@host */
  1685. X    *at = 0;
  1686. X    if (host_match = client_match(at + 1, item)) {
  1687. X        if (client->user[0] == 0) {
  1688. X        if (client->sock_type != FROM_CONNECTED) {
  1689. X            client->user = FROM_UNKNOWN;
  1690. X        } else if (client->sin == 0) {
  1691. X            syslog(LOG_ERR, "no socket info for user name lookup");
  1692. X            client->user = FROM_UNKNOWN;
  1693. X        } else {
  1694. X            client->user = rfc931_name(client->sin);
  1695. X        }
  1696. X        }
  1697. X        user_match = string_match(tok, client->user);
  1698. X        if (user_match == NO || user_match == FAIL) {
  1699. X        match = user_match;
  1700. X        } else {
  1701. X        match = host_match;
  1702. X        }
  1703. X    }
  1704. X    *at = '@';
  1705. X    } else {                    /* host */
  1706. X    match = client_match(tok, item);
  1707. X    }
  1708. X    return (match);
  1709. X}
  1710. X
  1711. X#endif /* USER_AT_HOST */
  1712. X
  1713. X/* string_match - match string against token */
  1714. X
  1715. Xstatic int string_match(tok, string)
  1716. Xchar   *tok;
  1717. Xchar   *string;
  1718. X{
  1719. X    int     tok_len;
  1720. X    int     str_len;
  1721. X    char   *cut;
  1722. X#ifdef    NETGROUP
  1723. X    static char *mydomain = 0;
  1724. X#endif
  1725. X
  1726. X    /*
  1727. X     * Return YES if a token has the magic value "ALL". Return FAIL if the
  1728. X     * token is "FAIL". If the token starts with a "." (domain name), return
  1729. X     * YES if it matches the last fields of the string. If the token has the
  1730. X     * magic value "LOCAL", return YES if the string does not contain a "."
  1731. X     * character. If the token ends on a "." (network number), return YES if
  1732. X     * it matches the first fields of the string. If the token begins with a
  1733. X     * "@" (netgroup name), return YES if the string is a (host) member of
  1734. X     * the netgroup. Return YES if the token fully matches the string. If the
  1735. X     * token is a netnumber/netmask pair, return YES if the address is a
  1736. X     * member of the specified subnet.
  1737. X     */
  1738. X
  1739. X    if (tok[0] == '.') {            /* domain: match last fields */
  1740. X    if ((str_len = strlen(string)) > (tok_len = strlen(tok))
  1741. X        && strcasecmp(tok, string + str_len - tok_len) == 0)
  1742. X        return (YES);
  1743. X    } else if (tok[0] == '@') {            /* netgroup: look it up */
  1744. X#ifdef    NETGROUP
  1745. X    if (mydomain == 0)
  1746. X        yp_get_default_domain(&mydomain);
  1747. X    if (!isdigit(string[0])
  1748. X        && innetgr(tok + 1, string, (char *) 0, mydomain))
  1749. X        return (YES);
  1750. X#else
  1751. X    syslog(LOG_ERR, "wrapper: netgroup support is not configured");
  1752. X    return (NO);
  1753. X#endif
  1754. X    } else if (strcasecmp(tok, "ALL") == 0) {    /* all: match any */
  1755. X    return (YES);
  1756. X    } else if (strcasecmp(tok, "FAIL") == 0) {    /* fail: match any */
  1757. X    return (FAIL);
  1758. X    } else if (strcasecmp(tok, "LOCAL") == 0) {    /* local: no dots */
  1759. X    if (strchr(string, '.') == 0 && strcasecmp(string, "unknown") != 0)
  1760. X        return (YES);
  1761. X    } else if (!strcasecmp(tok, string)) {    /* match host name or address */
  1762. X    return (YES);
  1763. X    } else if (tok[(tok_len = strlen(tok)) - 1] == '.') {    /* network */
  1764. X    if (strncmp(tok, string, tok_len) == 0)
  1765. X        return (YES);
  1766. X    } else if ((cut = strchr(tok, '/')) != 0) {    /* netnumber/netmask */
  1767. X    if (isdigit(string[0]) && masked_match(tok, cut, string))
  1768. X        return (YES);
  1769. X    }
  1770. X    return (NO);
  1771. X}
  1772. X
  1773. X/* masked_match - match address against netnumber/netmask */
  1774. X
  1775. Xstatic int masked_match(tok, slash, string)
  1776. Xchar   *tok;
  1777. Xchar   *slash;
  1778. Xchar   *string;
  1779. X{
  1780. X    unsigned long net;
  1781. X    unsigned long mask;
  1782. X    unsigned long addr;
  1783. X
  1784. X    if ((addr = inet_addr(string)) == INADDR_NONE)
  1785. X    return (NO);
  1786. X    *slash = 0;
  1787. X    net = inet_addr(tok);
  1788. X    *slash = '/';
  1789. X    if (net == INADDR_NONE || (mask = inet_addr(slash + 1)) == INADDR_NONE) {
  1790. X    syslog(LOG_ERR, "bad net/mask access control: %s", tok);
  1791. X    return (NO);
  1792. X    }
  1793. X    return ((addr & mask) == net);
  1794. X}
  1795. X
  1796. X/* xgets - fgets() with backslash-newline stripping */
  1797. X
  1798. Xstatic char *xgets(buf, len, fp)
  1799. Xchar   *buf;
  1800. Xint     len;
  1801. XFILE   *fp;
  1802. X{
  1803. X    int     got;
  1804. X    char   *start = buf;
  1805. X
  1806. X    for (;;) {
  1807. X    if (fgets(buf, len, fp) == 0)
  1808. X        return (buf > start ? start : 0);
  1809. X    got = strlen(buf);
  1810. X    if (got >= 2 && buf[got - 2] == '\\' && buf[got - 1] == '\n') {
  1811. X        got -= 2;
  1812. X        buf += got;
  1813. X        len -= got;
  1814. X        buf[0] = 0;
  1815. X    } else {
  1816. X        return (start);
  1817. X    }
  1818. X    }
  1819. X}
  1820. END_OF_hosts_access.c
  1821. if test 11173 -ne `wc -c <hosts_access.c`; then
  1822.     echo shar: \"hosts_access.c\" unpacked with wrong size!
  1823. fi
  1824. # end of overwriting check
  1825. fi
  1826. if test -f shell_cmd.c -a "${1}" != "-c" ; then 
  1827.   echo shar: Will not over-write existing file \"shell_cmd.c\"
  1828. else
  1829. echo shar: Extracting \"shell_cmd.c\" \(2883 characters\)
  1830. sed "s/^X//" >shell_cmd.c <<'END_OF_shell_cmd.c'
  1831. X /*
  1832. X  * shell_cmd() takes a shell command template and performs %a (host
  1833. X  * address), %c (client info), %h (host name or address), %d (daemon name),
  1834. X  * %p (process id) and %u (user name) substitutions. The result is executed
  1835. X  * by a /bin/sh child process, with standard input, standard output and
  1836. X  * standard error connected to /dev/null.
  1837. X  * 
  1838. X  * Diagnostics are reported through syslog(3).
  1839. X  * 
  1840. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  1841. X  */
  1842. X
  1843. X#ifndef lint
  1844. Xstatic char sccsid[] = "@(#) shell_cmd.c 1.3 93/03/07 22:47:39";
  1845. X#endif
  1846. X
  1847. X/* System libraries. */
  1848. X
  1849. X#include <sys/types.h>
  1850. X#include <sys/param.h>
  1851. X#include <signal.h>
  1852. X#include <stdio.h>
  1853. X#include <syslog.h>
  1854. X
  1855. Xextern char *strncpy();
  1856. Xextern void closelog();
  1857. Xextern void exit();
  1858. X
  1859. X/* Local stuff. */
  1860. X
  1861. X#include "log_tcp.h"
  1862. X
  1863. X/* Forward declarations. */
  1864. X
  1865. Xstatic void do_child();
  1866. X
  1867. X/* shell_cmd - expand %<char> sequences and execute shell command */
  1868. X
  1869. Xvoid    shell_cmd(string, daemon, client)
  1870. Xchar   *string;
  1871. Xchar   *daemon;
  1872. Xstruct from_host *client;
  1873. X{
  1874. X    char    cmd[BUFSIZ];
  1875. X    int     child_pid;
  1876. X    int     wait_pid;
  1877. X    int     daemon_pid = getpid();
  1878. X
  1879. X    /*
  1880. X     * Most of the work is done within the child process, to minimize the
  1881. X     * risk of damage to the parent.
  1882. X     */
  1883. X
  1884. X    switch (child_pid = fork()) {
  1885. X    case -1:                    /* error */
  1886. X    syslog(LOG_ERR, "fork: %m");
  1887. X    break;
  1888. X    case 00:                    /* child */
  1889. X    percent_x(cmd, sizeof(cmd), string, daemon, client, daemon_pid);
  1890. X    do_child(daemon, cmd);
  1891. X    /* NOTREACHED */
  1892. X    default:                    /* parent */
  1893. X    while ((wait_pid = wait((int *) 0)) != -1 && wait_pid != child_pid)
  1894. X         /* void */ ;
  1895. X    }
  1896. X}
  1897. X
  1898. X/* do_child - exec command with { stdin, stdout, stderr } to /dev/null */
  1899. X
  1900. Xstatic void do_child(myname, command)
  1901. Xchar   *myname;
  1902. Xchar   *command;
  1903. X{
  1904. X    char   *error = 0;
  1905. X    int     tmp_fd;
  1906. X
  1907. X    /*
  1908. X     * SunOS 4.x may send a SIGHUP to grandchildren if the child exits first.
  1909. X     * Sessions and process groups make old and grown-up programmers tear out
  1910. X     * what little hair is left and run away crying.
  1911. X     */
  1912. X
  1913. X    signal(SIGHUP, SIG_IGN);
  1914. X
  1915. X    /*
  1916. X     * Close a bunch of file descriptors. The Ultrix inetd only passes stdin,
  1917. X     * but other inetd implementations set up stdout as well. Ignore errors.
  1918. X     */
  1919. X
  1920. X    closelog();
  1921. X    for (tmp_fd = 0; tmp_fd < 10; tmp_fd++)
  1922. X    (void) close(tmp_fd);
  1923. X
  1924. X    /* Set up new stdin, stdout, stderr, and exec the shell command. */
  1925. X
  1926. X    if (open("/dev/null", 2) != 0) {
  1927. X    error = "open /dev/null: %m";
  1928. X    } else if (dup(0) != 1 || dup(0) != 2) {
  1929. X    error = "dup: %m";
  1930. X    } else {
  1931. X    (void) execl("/bin/sh", "sh", "-c", command, (char *) 0);
  1932. X    error = "execl /bin/sh: %m";
  1933. X    }
  1934. X
  1935. X    /* We can reach the following code only if there was an error. */
  1936. X
  1937. X#ifdef LOG_MAIL
  1938. X    (void) openlog(myname, LOG_PID, FACILITY);
  1939. X#else
  1940. X    (void) openlog(myname, LOG_PID);
  1941. X#endif
  1942. X    syslog(LOG_ERR, error);
  1943. X    exit(0);
  1944. X}
  1945. END_OF_shell_cmd.c
  1946. if test 2883 -ne `wc -c <shell_cmd.c`; then
  1947.     echo shar: \"shell_cmd.c\" unpacked with wrong size!
  1948. fi
  1949. # end of overwriting check
  1950. fi
  1951. if test -f log_tcp.h -a "${1}" != "-c" ; then 
  1952.   echo shar: Will not over-write existing file \"log_tcp.h\"
  1953. else
  1954. echo shar: Extracting \"log_tcp.h\" \(1448 characters\)
  1955. sed "s/^X//" >log_tcp.h <<'END_OF_log_tcp.h'
  1956. X/* @(#) log_tcp.h 1.3 93/03/07 22:47:41 */
  1957. X
  1958. X/* Location of the access control files. */
  1959. X
  1960. X#ifndef HOSTS_ALLOW
  1961. X#define HOSTS_ALLOW    "/etc/hosts.allow"
  1962. X#endif
  1963. X
  1964. X#ifndef HOSTS_DENY
  1965. X#define HOSTS_DENY    "/etc/hosts.deny"
  1966. X#endif
  1967. X
  1968. X /* Structure filled in by the fromhost() routine. */
  1969. X
  1970. Xstruct from_host {
  1971. X    int     sock_type;            /* socket type, see below */
  1972. X    char   *name;            /* host name */
  1973. X    char   *addr;            /* host address */
  1974. X    char   *user;            /* user name */
  1975. X    struct sockaddr_in *sin;        /* their side of the link */
  1976. X};
  1977. X
  1978. X#define FROM_UNKNOWN    "unknown"    /* name or address lookup failed */
  1979. X#define FROM_HOST(f) \
  1980. X    (((f)->name[0] && strcmp((f)->name, FROM_UNKNOWN)) ? (f)->name : (f)->addr)
  1981. X
  1982. X#define FROM_ADDRLEN    (4*3+3+1)    /* string with IP address */
  1983. X
  1984. X/* Socket types: 0 means unknown. */
  1985. X
  1986. X#define FROM_CONNECTED        1    /* connection-oriented */
  1987. X#define FROM_UNCONNECTED    2    /* non connection-oriented */
  1988. X
  1989. X/* Global functions. */
  1990. X
  1991. Xextern int fromhost();            /* get/validate remote host info */
  1992. Xextern int hosts_access();        /* access control */
  1993. Xextern void refuse();            /* refuse request */
  1994. Xextern void shell_cmd();        /* execute shell command */
  1995. Xextern void percent_x();        /* do %<char> expansion */
  1996. Xextern char *rfc931_name();        /* remote name from RFC 931 daemon */
  1997. Xextern char *hosts_info();        /* show origin of connection */
  1998. Xextern void clean_exit();        /* clean up and exit */
  1999. X
  2000. X/* Global variables. */
  2001. X
  2002. Xextern int log_severity;        /* for connection logging */
  2003. END_OF_log_tcp.h
  2004. if test 1448 -ne `wc -c <log_tcp.h`; then
  2005.     echo shar: \"log_tcp.h\" unpacked with wrong size!
  2006. fi
  2007. # end of overwriting check
  2008. fi
  2009. if test -f try.c -a "${1}" != "-c" ; then 
  2010.   echo shar: Will not over-write existing file \"try.c\"
  2011. else
  2012. echo shar: Extracting \"try.c\" \(3200 characters\)
  2013. sed "s/^X//" >try.c <<'END_OF_try.c'
  2014. X /*
  2015. X  * try - program to try out host access-control tables, including the
  2016. X  * optional shell commands.
  2017. X  * 
  2018. X  * usage: try process_name host_name_or_address
  2019. X  * 
  2020. X  * where process_name is a daemon process name (argv[0] value). If a host name
  2021. X  * is specified, both the name and address will be used to check the address
  2022. X  * control tables. If a host address is specified, the program pretends that
  2023. X  * host name lookup failed.
  2024. X  * 
  2025. X  * Most errors will be reported to the syslog daemon, so you'd better keep a
  2026. X  * tail on the logfile.
  2027. X  */
  2028. X
  2029. X#ifndef lint
  2030. Xstatic char sccsid[] = "@(#) try.c 1.3 93/03/07 22:47:43";
  2031. X#endif
  2032. X
  2033. X#include <sys/types.h>
  2034. X#include <netinet/in.h>
  2035. X#include <arpa/inet.h>
  2036. X#include <netdb.h>
  2037. X#include <stdio.h>
  2038. X#include <syslog.h>
  2039. X
  2040. X#ifdef HOSTS_ACCESS
  2041. X
  2042. X#ifndef    INADDR_NONE
  2043. X#define    INADDR_NONE    (-1)        /* XXX should be 0xffffffff */
  2044. X#endif
  2045. X
  2046. X#include "log_tcp.h"
  2047. X
  2048. X#ifdef INET_ADDR_BUG
  2049. X#include "inet_addr_fix"
  2050. X#endif
  2051. X
  2052. Xint     log_severity = SEVERITY;    /* run-time adjustable */
  2053. X
  2054. X/* Try out a (daemon,client) pair */
  2055. X
  2056. Xtry(daemon, name, addr)
  2057. Xchar   *daemon;
  2058. Xchar   *name;
  2059. Xchar   *addr;
  2060. X{
  2061. X    printf(" Daemon:   %s\n", daemon);
  2062. X    printf(" Hostname: %s\n", name);
  2063. X    printf(" Address:  %s\n", addr);
  2064. X    printf(" Access:   %s\n",
  2065. X       hosts_ctl(daemon, name, addr, "you") ? "granted" : "denied");
  2066. X}
  2067. X
  2068. X/* function to intercept the real shell_cmd() */
  2069. X
  2070. Xvoid    shell_cmd(cmd, daemon, client)
  2071. Xchar   *cmd;
  2072. Xchar   *daemon;
  2073. Xstruct from_host *client;
  2074. X{
  2075. X    char    buf[BUFSIZ];
  2076. X    int     pid = getpid();
  2077. X
  2078. X    percent_x(buf, sizeof(buf), cmd, daemon, client, pid);
  2079. X    printf(" Command:  %s\n", buf);
  2080. X}
  2081. X
  2082. X/* function to intercept the real process_options() */
  2083. X
  2084. Xprocess_options(options, daemon, client)
  2085. Xchar   *options;
  2086. Xchar   *daemon;
  2087. Xstruct from_host *client;
  2088. X{
  2089. X    char    buf[BUFSIZ];
  2090. X    int     pid = getpid();
  2091. X
  2092. X    percent_x(buf, sizeof(buf), options, daemon, client, pid);
  2093. X    printf(" Options:  %s\n", buf);
  2094. X}
  2095. X
  2096. Xmain(argc, argv)
  2097. Xint     argc;
  2098. Xchar  **argv;
  2099. X{
  2100. X    struct hostent *hp;
  2101. X
  2102. X#ifdef LOG_MAIL
  2103. X    openlog(argv[0], LOG_PID, FACILITY);
  2104. X#else
  2105. X    openlog(argv[0], LOG_PID);
  2106. X#endif
  2107. X
  2108. X    /*
  2109. X     * Abuse inet_addr() to find out if a host name or address was specified.
  2110. X     * 
  2111. X     * If a host address is specified, pretend that the host name lookup failed.
  2112. X     * This allows us to simulate the effect of host name lookup failures.
  2113. X     * 
  2114. X     * If a host name is specified, insist that the address is known. The reason
  2115. X     * for giving up is that in real life, a host address is always
  2116. X     * available.
  2117. X     */
  2118. X
  2119. X    if (argc != 3) {
  2120. X    fprintf(stderr, "usage: %s process_name host_name_or_address\n",
  2121. X        argv[0]);
  2122. X    return (1);
  2123. X    }
  2124. X    if (inet_addr(argv[2]) != INADDR_NONE) {    /* address specified */
  2125. X    try(argv[1], FROM_UNKNOWN, argv[2]);
  2126. X    return (0);
  2127. X    }
  2128. X    if ((hp = gethostbyname(argv[2])) == 0) {    /* address lookup fails */
  2129. X    fprintf(stderr, "host %s: address lookup failed\n", argv[2]);
  2130. X    return (1);
  2131. X    }
  2132. X    while (hp->h_addr_list[0])            /* name and address known */
  2133. X    try(argv[1], hp->h_name,
  2134. X        inet_ntoa(*(struct in_addr *) * hp->h_addr_list++));
  2135. X    return (0);
  2136. X}
  2137. X
  2138. X#else
  2139. X
  2140. Xmain()
  2141. X{
  2142. X    fprintf(stderr, "host access control is not enabled.\n");
  2143. X    return (1);
  2144. X}
  2145. X
  2146. X#endif
  2147. END_OF_try.c
  2148. if test 3200 -ne `wc -c <try.c`; then
  2149.     echo shar: \"try.c\" unpacked with wrong size!
  2150. fi
  2151. # end of overwriting check
  2152. fi
  2153. if test -f refuse.c -a "${1}" != "-c" ; then 
  2154.   echo shar: Will not over-write existing file \"refuse.c\"
  2155. else
  2156. echo shar: Extracting \"refuse.c\" \(737 characters\)
  2157. sed "s/^X//" >refuse.c <<'END_OF_refuse.c'
  2158. X /*
  2159. X  * refuse() reports a refused connection, and takes the consequences: in
  2160. X  * case of a datagram-oriented service, the unread datagram is taken from
  2161. X  * the input queue (or inetd would see the same datagram again and again);
  2162. X  * the program is terminated.
  2163. X  * 
  2164. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  2165. X  */
  2166. X
  2167. X#ifndef lint
  2168. Xstatic char sccsid[] = "@(#) refuse.c 1.2 92/06/11 22:21:34";
  2169. X#endif
  2170. X
  2171. X/* System libraries. */
  2172. X
  2173. X#include <syslog.h>
  2174. X
  2175. X/* Local stuff. */
  2176. X
  2177. X#include "log_tcp.h"
  2178. X
  2179. X/* refuse - refuse request from bad host */
  2180. X
  2181. Xvoid    refuse(client)
  2182. Xstruct from_host *client;
  2183. X{
  2184. X    syslog(LOG_WARNING, "refused connect from %s", hosts_info(client));
  2185. X    clean_exit(client);
  2186. X    /* NOTREACHED */
  2187. X}
  2188. END_OF_refuse.c
  2189. if test 737 -ne `wc -c <refuse.c`; then
  2190.     echo shar: \"refuse.c\" unpacked with wrong size!
  2191. fi
  2192. # end of overwriting check
  2193. fi
  2194. if test -f Makefile.dist -a "${1}" != "-c" ; then 
  2195.   echo shar: Will not over-write existing file \"Makefile.dist\"
  2196. else
  2197. echo shar: Extracting \"Makefile.dist\" \(15575 characters\)
  2198. sed "s/^X//" >Makefile.dist <<'END_OF_Makefile.dist'
  2199. X# @(#) Makefile.dist 1.2 93/03/24 22:42:41
  2200. X# 
  2201. X# If you did not already do so, copy the file Makefile.dist to Makefile
  2202. X# and edit the copy, not the original. Have a copy of the README file at
  2203. X# hand while editing. It gives some additional background.
  2204. X#
  2205. X# For your convenience, all configurable parameters have been moved into
  2206. X# the Makefile, so that you do not have to hack the source files anymore.
  2207. X#
  2208. X# Some parameters must always be set to match the operating environment.
  2209. X# Other parameter settings are a matter of taste. Their sections headings
  2210. X# are labeled "(Optional)". The defaults correspond to the programs as
  2211. X# documented in the manual pages.
  2212. X
  2213. X######################################################
  2214. X# Choice between easy and advanced installation recipe
  2215. X# 
  2216. X# According to the easy installation recipe in the README file, vendor-
  2217. X# provided network daemons are moved to "some other" directory, and the
  2218. X# tcpd wrapper fills in the "holes". For this mode of operation, the
  2219. X# REAL_DAEMON_DIR macro should be set to the "some other" directory.
  2220. X# Uncomment the appropriate line. The "..." is here for historical
  2221. X# reasons only; you will probably want to use some other name. Watch out
  2222. X# for the quotes and backslashes.
  2223. X
  2224. XREAL_DAEMON_DIR=\"/usr/etc/...\"    # BSD 4.3 Ultrix 4.x SunOS 4.x
  2225. X#REAL_DAEMON_DIR=\"/usr/sbin/...\"    # SysV.4 Solaris 2.x
  2226. X#REAL_DAEMON_DIR=\"/usr/libexec/...\"    # BSD 4.4
  2227. X
  2228. X# According to the advanced installation recipe, vendor-provided daemons
  2229. X# are left alone, and the inetd file is edited instead. In that case, the
  2230. X# REAL_DAEMON_DIR macro should reflect the actual directory with (most of)
  2231. X# your vendor-provided network daemons.  Uncomment the appropriate line.
  2232. X
  2233. X#REAL_DAEMON_DIR=\"/usr/etc\"        # BSD 4.3 Ultrix 4.x SunOS 4.x
  2234. X#REAL_DAEMON_DIR=\"/usr/sbin\"        # SysV.4 Solaris 2.x
  2235. X#REAL_DAEMON_DIR=\"/usr/libexec\"    # BSD 4.4
  2236. X
  2237. X#########################################################
  2238. X# Differences between ranlib(1) and ar(1) implementations
  2239. X#
  2240. X# Some C compilers (Ultrix 4.x) insist that ranlib(1) be run on an object
  2241. X# library; some don't care as long as the modules are in the right order;
  2242. X# some systems don't even have a ranlib(1) command. SGI IRIX uses the 's'
  2243. X# option to the 'ar' command instead. Make your choice.
  2244. X
  2245. XRANLIB    = ranlib    # have ranlib (BSD-ish UNIX)
  2246. X#RANLIB    = echo        # no ranlib (SYSV-ish UNIX)
  2247. X
  2248. XARFLAGS    = rv        # OK for most systems
  2249. X#ARFLAGS= rvs        # ranlib flag for 'ar' on IRIX 4.0.x
  2250. X
  2251. X#######################################################
  2252. X# Routines that are not present in the system libraries
  2253. X# 
  2254. X# The strcasecmp.c file provided with this package comes from 4.3+BSD
  2255. X# UNIX. The setenv.c module is a re-implementation of the 4.4 BSD one.
  2256. X# strtok.c comes from 4.4BSD. 
  2257. X
  2258. XAUX_OBJ    = setenv.o            # no setenv(3)
  2259. X#AUX_OBJ= setenv.o strcasecmp.o        # no setenv(3) and no strcasecmp(3)
  2260. X#AUX_OBJ= setenv.o strcasecmp.o strtok.o
  2261. X
  2262. X# While building the file strcasecmp.o, the compiler may complain that
  2263. X# u_char is undefined. Uncomment the following definition for a fix.
  2264. X#
  2265. X#UCHAR    = -Du_char="unsigned char"    # no u_char type
  2266. X
  2267. X# Uncomment the following if your C library has index/rindex/bcmp
  2268. X# but does not provide the strchr/strrchr/memcmp routines. If that
  2269. X# is the case, you probably also do not have strtok() (see above).
  2270. X#
  2271. X#STRINGS= -Dindex=strchr -Drindex=strrchr -Dmemcmp=bcmp
  2272. X
  2273. X###########################################
  2274. X# Selection of non-default object libraries
  2275. X#
  2276. X# Many System-V versions require that you explicitly specify the networking
  2277. X# libraries (for example, -lnet or -linet).
  2278. X#
  2279. X#LIBS    = -lsocket -lnsl    # SysV.4 Solaris 2.x
  2280. X#LIBS    = -lsun            # IRIX
  2281. X
  2282. X#########################
  2283. X# Ultrix-specific section
  2284. X#
  2285. X# Ultrix users may want to use the miscd wrapper, too. The Ultrix miscd
  2286. X# implements among others the SYSTAT service which runs the WHO command,
  2287. X# and thus provides a subset of the finger service. The very first wrapper
  2288. X# application (in the early hours of May 20, 1990) was to monitor SYSTAT.
  2289. X
  2290. Xall:    tcpd try            # no Ultrix miscd
  2291. X#all:    tcpd try miscd            # Ultrix, monitor systat etc. too
  2292. X
  2293. X#REAL_MISCD=\"/usr/etc/.../miscd\"    # easy installation
  2294. X#REAL_MISCD=\"/usr/etc/miscd\"        # advanced installation
  2295. X
  2296. X################################
  2297. X# System-specific compiler flags
  2298. X#
  2299. X# Apollo Domain/OS offers both bsd and sys5 environments, sometimes
  2300. X# on the same machine.  If your Apollo is primarily sys5.3 and also
  2301. X# has bsd4.3, uncomment the following to build under bsd and run under
  2302. X# either environment.
  2303. X#
  2304. X#SYSTYPE= -A run,any -A sys,any
  2305. X
  2306. X# For MIPS RISC/os 4_52.p3, uncomment the following definition.
  2307. X#
  2308. X#SYSTYPE= -sysname bsd43
  2309. X
  2310. X############################
  2311. X# Working around system bugs
  2312. X#
  2313. X# Some versions of Apollo or SYSV.4 UNIX have a bug in the getpeername(2)
  2314. X# routine.  You may have this bug when the wrapper reports that all UDP
  2315. X# connections come from address 0.0.0.0. Compile with -DGETPEERNAME_BUG
  2316. X# for a workaround. The workaround does no harm on other systems. If in
  2317. X# doubt, leave it in.
  2318. X#
  2319. X# Some System V versions (Solaris 2) have a problem in the recvfrom()
  2320. X# emulation code.  You may have this bug when the wrapper programs
  2321. X# complain about "unexpected address family 0" when processing an UDP
  2322. X# request. Compile with -DRECVFROM_BUG for a workaround. The workaround
  2323. X# does no harm on other systems. If in doubt, leave it in.
  2324. X# 
  2325. X# With some System V implementations (SCO UNIX 3.2v4), even compiling
  2326. X# with -DRECVFROM_BUG does not solve the "address family 0" problem. If
  2327. X# that is the case, compile with -DADDRESS_FAMILY_BUG instead.
  2328. X#
  2329. X# DG/UX 5.4.1 comes with an inet_ntoa() function that returns a structure
  2330. X# instead of a long integer. Compile with -DINET_ADDR_BUG to work around
  2331. X# this mutant behavour.
  2332. X
  2333. XBUGS    = -DGETPEERNAME_BUG -DRECVFROM_BUG # -DADDRESS_FAMILY_BUG
  2334. X
  2335. X####################################################
  2336. X# Whether or not your system has NIS (or YP) support
  2337. X#
  2338. X# If your system supports NIS or YP-style netgroups, enable the following
  2339. X# macro definition. Netgroups are used only for host access control.
  2340. X#
  2341. X#NETGROUP= -DNETGROUP
  2342. X
  2343. X# End of the required configuration options; all other ones are optional.
  2344. X#########################################################################
  2345. X
  2346. X################################################################
  2347. X# Changing the default disposition of logfile records (Optional)
  2348. X#
  2349. X# By default, logfile entries are written to the same file as used for
  2350. X# sendmail transaction logs. See your /etc/syslog.conf file for actual
  2351. X# path names of logfiles. The tutorial section in the README file
  2352. X# gives a brief introduction to the syslog daemon.
  2353. X# 
  2354. X# Change the FACILITY definition below if you disagree with the default
  2355. X# disposition. Some syslog versions (including Ultrix 4.x) do not provide
  2356. X# this flexibility.
  2357. X# 
  2358. X# If nothing shows up on your system, it may be that the syslog records
  2359. X# are sent to a dedicated loghost. It may also be that no syslog daemon
  2360. X# is running at all. The README file gives pointers to surrogate syslog
  2361. X# implementations for systems that have no syslog library routines or
  2362. X# no syslog daemons.
  2363. X#
  2364. X# The LOG_XXX names below are taken from the /usr/include/syslog.h file.
  2365. X
  2366. XFACILITY= LOG_MAIL    # LOG_MAIL is what most sendmail daemons use
  2367. X
  2368. X# The syslog priority at which successful connections are logged.
  2369. X
  2370. XSEVERITY= LOG_INFO    # LOG_INFO is normally not logged to the console
  2371. X
  2372. X#############################################
  2373. X# Enabling remote username lookups (Optional)
  2374. X#
  2375. X# By default, the wrappers just report the remote host name (the host
  2376. X# address if the host name lookup fails or times out).  Username lookups
  2377. X# require that the remote host runs a daemon that supports a RFC 931 like
  2378. X# protocol.  Remote user name lookups are not possible for UDP-based
  2379. X# connections, and can cause noticeable delays with connections from
  2380. X# non-UNIX PCs.  On some systems, remote username lookups can trigger a
  2381. X# kernel bug, causing loss of service. The README file gives details on
  2382. X# how to find out if your system has that problem.
  2383. X# 
  2384. X# Uncomment the following definition if the wrappers should always
  2385. X# attempt to get the remote user name.
  2386. X#
  2387. X# The default username lookup timeout is 30 seconds.
  2388. X#
  2389. X#AUTH    = -DRFC931_TIMEOUT=30 -DRFC931
  2390. X
  2391. X# The USER_AT_HOST feature does selective username lookups. It triggers
  2392. X# on access control patterns of the form xxx@yyy. Until now, such
  2393. X# patterns were not used, so that USER_AT_HOST does not break existing
  2394. X# rules.
  2395. X# 
  2396. X# The feature is not documented and is not yet intended for general use,
  2397. X# because it can complicate the design of access control tables.
  2398. X# 
  2399. X# With USER_AT_HOST enabled, remote username lookups are done only for
  2400. X# user_pattern@host_pattern expressions in the access control files, but
  2401. X# only when the host_pattern matches. Example: "ALL: @pcgroup ALL@ALL"
  2402. X# avoids user name lookups for members of the pcgroup netgroup.  The
  2403. X# user_pattern syntax is identical to that of host_pattern, but "ALL"
  2404. X# is usually the only user_pattern that makes sense.
  2405. X# 
  2406. X# The default username lookup timeout is 30 seconds.
  2407. X#
  2408. X#AUTH    = -DRFC931_TIMEOUT=30 -DUSER_AT_HOST
  2409. X
  2410. X########################################################
  2411. X# Turning on experimental language extensions (Optional)
  2412. X#
  2413. X# Instead of the officially documented access control language, the
  2414. X# software can be configured to implement a more experimental language
  2415. X# that is easily extended. The experimental language is implemented by
  2416. X# the "options.c" source module which also serves as its documentation.
  2417. X
  2418. XSTYLE    = -DOPTIONS_STYLE=shell_cmd        # The documented language
  2419. X#STYLE    = -DOPTIONS_STYLE=process_options    # The experimental one
  2420. X
  2421. X######################################################
  2422. X# Changing the default file protection mask (Optional)
  2423. X#
  2424. X# On many systems, network daemons and other system processes are started
  2425. X# with a zero umask value, so that world-writable files may be produced.
  2426. X# It is a good idea to edit your /etc/rc* files so that they begin with
  2427. X# an explicit umask setting.  On our site we use `umask 022' because it
  2428. X# does not break anything yet gives adequate protection against tampering.
  2429. X# 
  2430. X# The following macro specifies the default umask for processes run under
  2431. X# control of the daemon wrappers. Comment it out only if you are certain
  2432. X# that inetd and its children are started with a safe umask value.
  2433. X
  2434. XUMASK    = -DDAEMON_UMASK=022
  2435. X
  2436. X#######################################
  2437. X# Turning off access control (Optional)
  2438. X#
  2439. X# By default, host access control is enabled.  To disable host access
  2440. X# control, comment out the following definition.  Host access control
  2441. X# can also be turned off at runtime by providing no or empty access
  2442. X# control tables.
  2443. X
  2444. XACCESS    = -DHOSTS_ACCESS
  2445. X
  2446. X########################################################
  2447. X# Changing the access control table pathnames (Optional)
  2448. X#
  2449. X# The HOSTS_ALLOW and HOSTS_DENY macros define where the programs will
  2450. X# look for access control information. Watch out for the quotes and
  2451. X# backslashes when you make changes.
  2452. X
  2453. XTABLES    = -DHOSTS_DENY=\"/etc/hosts.deny\" -DHOSTS_ALLOW=\"/etc/hosts.allow\"
  2454. X
  2455. X###########################################
  2456. X# Turning off host NAME checking (Optional)
  2457. X#
  2458. X# By default, the software tries to protect against hosts that claim to
  2459. X# have someone elses host name. This is relevant for network services
  2460. X# whose authentication depends on host names, such as rsh and rlogin.
  2461. X#
  2462. X# With paranoid mode on, connections will be rejected when the host name
  2463. X# does not match the host address. Connections will also be rejected when
  2464. X# the host name cannot be verified because gethostbyname() fails.
  2465. X#
  2466. X# Comment out the following definition if you do not need this additional
  2467. X# protection. If paranoid mode is off, and a host name check fails, the
  2468. X# daemon wrappers will use only the host address, but your daemons may
  2469. X# still use the host name.
  2470. X
  2471. XPARANOID= -DPARANOID
  2472. X
  2473. X#############################################
  2474. X# Turning on host ADDRESS checking (Optional)
  2475. X#
  2476. X# Optionally, the software tries to protect against hosts that pretend to
  2477. X# have someone elses host address. This is relevant for network services
  2478. X# whose authentication depends on host names, such as rsh and rlogin,
  2479. X# because the network address is used to look up the remote host name.
  2480. X# 
  2481. X# The protection is effective only when the offending host claims to have
  2482. X# a network address that lies outside its own network.
  2483. X#
  2484. X# My site has been running rlogind and rshd daemons that implement this
  2485. X# feature for more than 2 years, and without any ill effects.
  2486. X#
  2487. X# This feature cannot be used with SunOS 4.x because of a kernel bug in
  2488. X# the implementation of the getsockopt() system call. Kernel panics have
  2489. X# been reported for SunOS 4.1.1 and SunOS 4.1.2. Symptoms are "BAD TRAP"
  2490. X# and "Data fault" while executing the tcp_ctloutput() kernel function.
  2491. X#
  2492. X# Uncomment the following macro definition if your getsockopt() is OK.
  2493. X#
  2494. X# KILL_OPT= -DKILL_IP_OPTIONS
  2495. X
  2496. X## End configuration options
  2497. X############################
  2498. X
  2499. XCFLAGS    = -O -DFACILITY=$(FACILITY) $(ACCESS) $(PARANOID) $(NETGROUP) \
  2500. X    $(BUGS) $(SYSTYPE) $(AUTH) $(UMASK) -DREAL_MISCD=$(REAL_MISCD) \
  2501. X    -DREAL_DAEMON_DIR=$(REAL_DAEMON_DIR) $(STYLE) $(KILL_OPT) \
  2502. X    -DSEVERITY=$(SEVERITY) $(UCHAR) $(TABLES) $(STRINGS)
  2503. X
  2504. XLIB_OBJ= hosts_access.o options.o shell_cmd.o rfc931.o hosts_info.o \
  2505. X    hosts_ctl.o refuse.o percent_x.o clean_exit.o $(AUX_OBJ) \
  2506. X    fromhost.o fix_options.o
  2507. X
  2508. XKIT    = README miscd.c tcpd.c fromhost.c hosts_access.c shell_cmd.c \
  2509. X    log_tcp.h try.c refuse.c Makefile.dist hosts_access.5 strcasecmp.c \
  2510. X    BLURB rfc931.c tcpd.8 hosts_info.c hosts_access.3 hosts_ctl.c \
  2511. X    percent_x.c options.c clean_exit.c setenv.c patchlevel.h strtok.c \
  2512. X    fix_options.c inet_addr_fix
  2513. X
  2514. XLIB    = libwrap.a
  2515. X
  2516. X$(LIB):    $(LIB_OBJ)
  2517. X    rm -f $(LIB)
  2518. X    ar $(ARFLAGS) $(LIB) $(LIB_OBJ)
  2519. X    $(RANLIB) $(LIB)
  2520. X
  2521. Xtcpd:    tcpd.o fromhost.o $(LIB)
  2522. X    $(CC) $(CFLAGS) -o $@ tcpd.o fromhost.o $(LIB) $(LIBS)
  2523. X
  2524. Xmiscd:    miscd.o fromhost.o $(LIB)
  2525. X    $(CC) $(CFLAGS) -o $@ miscd.o fromhost.o $(LIB) $(LIBS)
  2526. X
  2527. Xtry:    try.o $(LIB)
  2528. X    $(CC) $(CFLAGS) -o $@ try.o $(LIB) $(LIBS)
  2529. X
  2530. Xfromhost: fromhost.c log_tcp.h Makefile $(LIB)
  2531. X    $(CC) $(CFLAGS) -DTEST -o fromhost fromhost.c $(LIB) $(LIBS)
  2532. X    rm -f fromhost.o
  2533. X
  2534. Xshar:    $(KIT)
  2535. X    @shar $(KIT)
  2536. X
  2537. Xkit:    $(KIT)
  2538. X    @makekit $(KIT)
  2539. X
  2540. Xarchive:
  2541. X    $(ARCHIVE) $(KIT)
  2542. X
  2543. Xclean:
  2544. X    rm -f tcpd miscd try fromhost *.[oa] core
  2545. X
  2546. X# Enable all bells and whistles for linting.
  2547. X
  2548. Xlint: tcpd_lint miscd_lint try_lint
  2549. X
  2550. Xtcpd_lint:
  2551. X    lint -DFACILITY=LOG_MAIL -DHOSTS_ACCESS -DPARANOID -DNETGROUP \
  2552. X    -DGETPEERNAME_BUG -DDAEMON_UMASK=022 -DSEVERITY=$(SEVERITY) \
  2553. X    -DUSER_AT_HOST -DKILL_IP_OPTIONS -DOPTIONS_STYLE=process_options \
  2554. X    tcpd.c fromhost.c hosts_access.c shell_cmd.c refuse.c rfc931.c \
  2555. X    hosts_info.c percent_x.c clean_exit.c options.c setenv.c fix_options.c
  2556. X
  2557. Xmiscd_lint:
  2558. X    lint -DFACILITY=LOG_MAIL -DHOSTS_ACCESS -DPARANOID -DNETGROUP \
  2559. X    -DGETPEERNAME_BUG -DDAEMON_UMASK=022 -DSEVERITY=$(SEVERITY) \
  2560. X    -DUSER_AT_HOST -DKILL_IP_OPTIONS -DOPTIONS_STYLE=process_options \
  2561. X    miscd.c fromhost.c hosts_access.c shell_cmd.c refuse.c rfc931.c \
  2562. X    hosts_info.c percent_x.c clean_exit.c options.c setenv.c fix_options.c
  2563. X
  2564. Xtry_lint:
  2565. X    lint -DFACILITY=LOG_MAIL -DHOSTS_ACCESS -DNETGROUP try.c \
  2566. X    hosts_ctl.c hosts_access.c hosts_info.c percent_x.c
  2567. X
  2568. X# Compilation dependencies.
  2569. X
  2570. Xclean_exit.o: log_tcp.h Makefile
  2571. Xfix_options.o: log_tcp.h Makefile
  2572. Xfromhost.o: log_tcp.h Makefile
  2573. Xhosts_access.o: log_tcp.h Makefile
  2574. Xhosts_ctl.o: log_tcp.h Makefile
  2575. Xhosts_info.o: log_tcp.h Makefile
  2576. Xmiscd.o: patchlevel.h log_tcp.h Makefile
  2577. Xoptions.o: log_tcp.h Makefile
  2578. Xpercent_x.o: log_tcp.h Makefile
  2579. Xrefuse.o: log_tcp.h Makefile
  2580. Xrfc931.o: log_tcp.h Makefile
  2581. Xshell_cmd.o: log_tcp.h Makefile
  2582. Xtcpd.o: patchlevel.h log_tcp.h Makefile
  2583. Xtry.o: log_tcp.h Makefile
  2584. END_OF_Makefile.dist
  2585. if test 15575 -ne `wc -c <Makefile.dist`; then
  2586.     echo shar: \"Makefile.dist\" unpacked with wrong size!
  2587. fi
  2588. # end of overwriting check
  2589. fi
  2590. if test -f hosts_access.5 -a "${1}" != "-c" ; then 
  2591.   echo shar: Will not over-write existing file \"hosts_access.5\"
  2592. else
  2593. echo shar: Extracting \"hosts_access.5\" \(9533 characters\)
  2594. sed "s/^X//" >hosts_access.5 <<'END_OF_hosts_access.5'
  2595. X.TH HOSTS_ACCESS 5
  2596. X.SH NAME
  2597. Xhosts_access \- format of host access control files
  2598. X.SH DESCRIPTION
  2599. XThis manual page describes a simple access control language that is
  2600. Xbased on client (host name or address) and server (process name)
  2601. Xpatterns.  Examples are given at the end. The impatient reader can skip
  2602. Xto the EXAMPLES section for a quick introduction.
  2603. X.PP
  2604. XIn the following text, \fIdaemon\fR is the the process name of a
  2605. Xnetwork daemon process, and \fIclient\fR is the name and/or address of
  2606. Xa host requesting service. Network daemon process names are specified
  2607. Xin the inetd configuration file.
  2608. X.SH ACCESS CONTROL FILES
  2609. XThe access control software consults two files:
  2610. X.IP o
  2611. XAccess will be granted when a (daemon,client) pair matches an entry in
  2612. Xthe \fI/etc/hosts.allow\fR file.
  2613. X.IP o
  2614. XOtherwise, access will be denied when a (daemon,client) pair matches an
  2615. Xentry in the \fI/etc/hosts.deny\fR file.
  2616. X.IP o
  2617. XOtherwise, access will be granted.
  2618. X.PP
  2619. XA non-existing access control file is treated as if it were an empty
  2620. Xfile. Thus, access control can be turned off by providing no access
  2621. Xcontrol files.
  2622. X.SH ACCESS CONTROL RULES
  2623. XEach access control file consists of zero or more lines of text.  These
  2624. Xlines are processed in order of appearance. The search terminates when a
  2625. Xmatch is found.
  2626. X.IP o
  2627. XA newline character is ignored when it is preceded by a backslash
  2628. Xcharacter.
  2629. X.IP o
  2630. XBlank lines or lines that begin with a `#\' character are ignored.
  2631. X.IP o
  2632. XAll other lines should satisfy the following format, things between []
  2633. Xbeing optional:
  2634. X.sp
  2635. X.ti +3
  2636. Xdaemon_list : client_list [ : shell_command ]
  2637. X.PP
  2638. X\fIdaemon_list\fR is a list of one or more daemon process names
  2639. X(argv[0] values) or wildcards (see below).  
  2640. X.PP
  2641. X\fIclient_list\fR is a list
  2642. Xof one or more host names, host addresses, patterns or wildcards (see
  2643. Xbelow) that will be matched against the remote host name or address.
  2644. X.PP
  2645. XList elements should be separated by blanks and/or commas.  
  2646. X.PP
  2647. XWith the exception of NIS (YP) netgroup lookups, all access control
  2648. Xchecks are case insensitive.
  2649. X.br
  2650. X.ne 4
  2651. X.SH PATTERNS
  2652. XThe access control language implements the following patterns:
  2653. X.IP o
  2654. XA string that begins with a `.\' character.  A client name or address
  2655. Xis matched if its last components match the specified pattern.  For
  2656. Xexample, the pattern `.tue.nl\' matches the host name
  2657. X`wzv.win.tue.nl\'.
  2658. X.IP o
  2659. XA string that ends with a `.\' character.  A client name or address is
  2660. Xmatched if its first fields match the given string.  For example, the
  2661. Xpattern `131.155.\' matches the address of (almost) every host on the
  2662. XEind\%hoven University network (131.155.x.x).
  2663. X.IP o
  2664. XA string that begins with a `@\' character is treated as a netgroup
  2665. Xname.  Netgroups are usually supported on systems with NIS (formerly
  2666. XYP) data bases. A client host name is matched if it is a (host) member
  2667. Xof the specified netgroup.
  2668. X.IP o
  2669. XAn expression of the form `n.n.n.n/m.m.m.m\' is interpreted as a
  2670. X`net/mask\' pair. A client address is matched if `net\' is equal to the
  2671. Xbitwise AND of the address and the `mask\'. For example, the net/mask
  2672. Xpattern `131.155.72.0/255.255.254.0\' matches every address in the
  2673. Xrange `131.155.72.0\' through `131.155.73.255\'.
  2674. X.SH WILDCARDS
  2675. XThe access control language supports explicit wildcards:
  2676. X.IP ALL
  2677. XIf this token appears in a daemon_list, it matches all network daemon
  2678. Xprocess names.  If the ALL token appears in a client_list, it matches
  2679. Xall client names and addresses.
  2680. X.IP LOCAL
  2681. XMatches any string that does not contain a dot character.
  2682. XTypical use is in client_lists.
  2683. X.IP UNKNOWN
  2684. XMatches any host whose name and/or address lookup failed.  Should be
  2685. Xused with care, because host names may also be unavailable due to
  2686. Xtemporary name server problems.
  2687. X.IP FAIL
  2688. XLike the ALL wildcard, but causes the software to pretend that the scan
  2689. Xof the current access control table fails. FAIL is being phased out; it
  2690. Xwill become an undocumented feature. The EXCEPT operator (see below) is
  2691. Xa much cleaner alternative.
  2692. X.br
  2693. X.ne 6
  2694. X.SH OPERATORS
  2695. X.IP EXCEPT
  2696. XIntended use is of the form: `list_1 EXCEPT list_2\'; this construct
  2697. Xmatches anything that matches \fIlist_1\fR unless it matches
  2698. X\fIlist_2\fR.  This construct can be used in daemon_lists and in
  2699. Xclient_lists. The EXCEPT operator can be nested and is
  2700. Xright-associative (just like C's assignment operator).
  2701. X.br
  2702. X.ne 6
  2703. X.SH SHELL COMMANDS
  2704. XIf the first-matched access control rule contains a shell command, that
  2705. Xcommand is subjected to the following substitutions:
  2706. X.IP %a
  2707. Xexpands to the remote host address.
  2708. X.IP %c
  2709. Xexpands to client information: user@host, user@address, a host name, or
  2710. Xjust an address, depending on how much information is available.
  2711. X.IP %h
  2712. Xexpands to the remote host name (or address, if the host name is
  2713. Xunavailable).
  2714. X.IP %d
  2715. Xexpands to the daemon process name (argv[0] value).
  2716. X.IP %p
  2717. Xexpands to the daemon process id.
  2718. X.IP %u
  2719. Xexpands to the remote user name (or "unknown").
  2720. X.IP %%
  2721. Xexpands to a single `%\' character.
  2722. X.PP
  2723. XCharacters in % expansions that may confuse the shell are replaced by
  2724. Xunderscores.
  2725. XThe result is executed by a \fI/bin/sh\fR child process with standard
  2726. Xinput, output and error connected to \fI/dev/null\fR.  Specify an `&\'
  2727. Xat the end of the command if you do not want to wait until it has
  2728. Xcompleted.
  2729. X.PP
  2730. XShell commands should not rely on the PATH setting of the inetd.
  2731. XInstead, they should use absolute path names, or they should begin with
  2732. Xan explicit PATH=whatever statement.
  2733. X.SH EXAMPLES
  2734. XThe language is flexible enough that different types of access control
  2735. Xpolicy can be expressed with a minimum of fuss. Although the language
  2736. Xuses two access control tables, the most common policies can be
  2737. Ximplemented with one of the tables being trivial or even empty.
  2738. X.PP
  2739. XWhen reading the examples below it is important to realize that the
  2740. Xallow table is scanned before the deny table, that the search
  2741. Xterminates when a match is found, and that access is granted when no
  2742. Xmatch is found at all.
  2743. X.PP
  2744. XThe examples use host and domain names. They can be improved by
  2745. Xincluding address and/or network/netmask information, to reduce the
  2746. Ximpact of temporary name server lookup failures.
  2747. X.SH MOSTLY CLOSED
  2748. XIn this case, access is denied by default. Only explicitly authorized
  2749. Xhosts are permitted access. 
  2750. X.PP
  2751. XThe default policy (no access) is implemented with a trivial deny
  2752. Xfile:
  2753. X.PP
  2754. X.ne 2
  2755. X/etc/hosts.deny: 
  2756. X.in +3
  2757. XALL: ALL
  2758. X.PP
  2759. XThis denies all service to all hosts, unless they are permitted access
  2760. Xby entries in the allow file.
  2761. X.PP
  2762. XThe explicitly authorized hosts are listed in the allow file.
  2763. XFor example:
  2764. X.PP
  2765. X.ne 2
  2766. X/etc/hosts.allow: 
  2767. X.in +3
  2768. XALL: LOCAL @some_netgroup
  2769. X.br
  2770. XALL: .foobar.edu EXCEPT terminalserver.foobar.edu
  2771. X.PP
  2772. XThe first rule permits access to all services from hosts in the local
  2773. Xdomain (no `.\' in the host name) and from members of the
  2774. X\fIsome_netgroup\fP netgroup. The second rule permits access to all
  2775. Xservices from all hosts in the \fI.foobar.edu\fP domain, with the
  2776. Xexception of \fIterminalserver.foobar.edu\fP.
  2777. X.SH MOSTLY OPEN
  2778. XHere, access is granted by default; only explicitly specified hosts are
  2779. Xrefused service. 
  2780. X.PP
  2781. XThe default policy (access granted) makes the allow file redundant so
  2782. Xthat it can be omitted.  The explicitly non-authorized hosts are listed
  2783. Xin the deny file. For example:
  2784. X.PP
  2785. X/etc/hosts.deny:
  2786. X.in +3
  2787. XALL: some.host.name, .some.domain
  2788. X.br
  2789. XALL EXCEPT in.fingerd: other.host.name, .other.domain
  2790. X.PP
  2791. XThe first rule denies some hosts all services; the second rule still
  2792. Xpermits finger requests from other hosts.
  2793. X.SH BOOBY TRAPS
  2794. XThe next example permits tftp requests from hosts in the local domain.
  2795. XRequests from any other hosts are denied. Instead of the requested
  2796. Xfile, a finger probe is sent to the offending host. The result is
  2797. Xmailed to the superuser.
  2798. X.PP
  2799. X.ne 2
  2800. X/etc/hosts.allow:
  2801. X.in +3
  2802. X.nf
  2803. Xin.tftpd: LOCAL, .my.domain
  2804. X.PP
  2805. X.ne 2
  2806. X/etc/hosts.deny:
  2807. X.in +3
  2808. X.nf
  2809. Xin.tftpd: ALL: (/usr/ucb/finger -l @%h | /usr/ucb/mail -s %d-%h root) &
  2810. X.fi
  2811. X.PP
  2812. XThe expansion of the %h (remote host) and %d (service name) sequences
  2813. Xis described in the section on shell commands.
  2814. X.PP
  2815. XWarning: do not booby-trap your finger daemon, unless you are prepared
  2816. Xfor infinite finger loops.
  2817. X.PP
  2818. XOn network firewall systems this trick can be carried even further.
  2819. XThe typical network firewall only provides a limited set of services to
  2820. Xthe outer world. All other services can be "bugged" just like the above
  2821. Xtftp example. The result is an excellent early-warning system.
  2822. X.br
  2823. X.ne 4
  2824. X.SH DIAGNOSTICS
  2825. XAn error is reported when a syntax error is found in a host access
  2826. Xcontrol rule; when the length of an access control rule exceeds the
  2827. Xcapacity of an internal buffer; when an access control rule is not
  2828. Xterminated by a newline character; when the result of %<character>
  2829. Xexpansion would overflow an internal buffer; when a system call fails
  2830. Xthat shouldn\'t.  All problems are reported via the syslog daemon.
  2831. X.SH FILES
  2832. X.na
  2833. X.nf
  2834. X/etc/hosts.allow, (daemon,client) pairs that are granted access.
  2835. X/etc/hosts.deny, (daemon,client) pairs that are denied access.
  2836. X.ad
  2837. X.fi
  2838. X.SH SEE ALSO
  2839. Xtcpd(8) tcp/ip daemon wrapper program.
  2840. X.SH BUGS
  2841. XIf a name server lookup times out, the host name will not be available
  2842. Xto the access control software, even though the host is registered.
  2843. X.PP
  2844. XDomain name server lookups are case insensitive; NIS (formerly YP)
  2845. Xnetgroup lookups are case sensitive.
  2846. X.SH AUTHOR
  2847. X.na
  2848. X.nf
  2849. XWietse Venema (wietse@wzv.win.tue.nl)
  2850. XDepartment of Mathematics and Computing Science
  2851. XEindhoven University of Technology
  2852. XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  2853. X\" @(#) hosts_access.5 1.11 93/03/07 22:47:47
  2854. END_OF_hosts_access.5
  2855. if test 9533 -ne `wc -c <hosts_access.5`; then
  2856.     echo shar: \"hosts_access.5\" unpacked with wrong size!
  2857. fi
  2858. # end of overwriting check
  2859. fi
  2860. if test -f strcasecmp.c -a "${1}" != "-c" ; then 
  2861.   echo shar: Will not over-write existing file \"strcasecmp.c\"
  2862. else
  2863. echo shar: Extracting \"strcasecmp.c\" \(3767 characters\)
  2864. sed "s/^X//" >strcasecmp.c <<'END_OF_strcasecmp.c'
  2865. X/*
  2866. X * Copyright (c) 1987 Regents of the University of California.
  2867. X * All rights reserved.
  2868. X *
  2869. X * Redistribution and use in source and binary forms are permitted
  2870. X * provided that the above copyright notice and this paragraph are
  2871. X * duplicated in all such forms and that any documentation,
  2872. X * advertising materials, and other materials related to such
  2873. X * distribution and use acknowledge that the software was developed
  2874. X * by the University of California, Berkeley.  The name of the
  2875. X * University may not be used to endorse or promote products derived
  2876. X * from this software without specific prior written permission.
  2877. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  2878. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  2879. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  2880. X */
  2881. X
  2882. X#if defined(LIBC_SCCS) && !defined(lint)
  2883. Xstatic char sccsid[] = "@(#)strcasecmp.c    5.6 (Berkeley) 6/27/88";
  2884. X#endif /* LIBC_SCCS and not lint */
  2885. X
  2886. X#include <sys/types.h>
  2887. X
  2888. X/*
  2889. X * This array is designed for mapping upper and lower case letter
  2890. X * together for a case independent comparison.  The mappings are
  2891. X * based upon ascii character sequences.
  2892. X */
  2893. Xstatic u_char charmap[] = {
  2894. X    '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
  2895. X    '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
  2896. X    '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
  2897. X    '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
  2898. X    '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
  2899. X    '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
  2900. X    '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
  2901. X    '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
  2902. X    '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  2903. X    '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  2904. X    '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  2905. X    '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
  2906. X    '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  2907. X    '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  2908. X    '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  2909. X    '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
  2910. X    '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  2911. X    '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  2912. X    '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  2913. X    '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  2914. X    '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  2915. X    '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  2916. X    '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  2917. X    '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  2918. X    '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  2919. X    '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  2920. X    '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  2921. X    '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
  2922. X    '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  2923. X    '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  2924. X    '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  2925. X    '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
  2926. X};
  2927. X
  2928. Xstrcasecmp(s1, s2)
  2929. X    char *s1, *s2;
  2930. X{
  2931. X    register u_char    *cm = charmap,
  2932. X            *us1 = (u_char *)s1,
  2933. X            *us2 = (u_char *)s2;
  2934. X
  2935. X    while (cm[*us1] == cm[*us2++])
  2936. X        if (*us1++ == '\0')
  2937. X            return(0);
  2938. X    return(cm[*us1] - cm[*--us2]);
  2939. X}
  2940. X
  2941. Xstrncasecmp(s1, s2, n)
  2942. X    char *s1, *s2;
  2943. X    register int n;
  2944. X{
  2945. X    register u_char    *cm = charmap,
  2946. X            *us1 = (u_char *)s1,
  2947. X            *us2 = (u_char *)s2;
  2948. X
  2949. X    while (--n >= 0 && cm[*us1] == cm[*us2++])
  2950. X        if (*us1++ == '\0')
  2951. X            return(0);
  2952. X    return(n < 0 ? 0 : cm[*us1] - cm[*--us2]);
  2953. X}
  2954. END_OF_strcasecmp.c
  2955. if test 3767 -ne `wc -c <strcasecmp.c`; then
  2956.     echo shar: \"strcasecmp.c\" unpacked with wrong size!
  2957. fi
  2958. # end of overwriting check
  2959. fi
  2960. if test -f BLURB -a "${1}" != "-c" ; then 
  2961.   echo shar: Will not over-write existing file \"BLURB\"
  2962. else
  2963. echo shar: Extracting \"BLURB\" \(2068 characters\)
  2964. sed "s/^X//" >BLURB <<'END_OF_BLURB'
  2965. X@(#) BLURB 1.8 93/03/24 22:42:37
  2966. X
  2967. XWith the programs that come with this kit you can monitor incoming
  2968. Xrequests for IP services such as TFTP, EXEC, FTP, RSH, TELNET, RLOGIN,
  2969. XFINGER, SYSTAT, and many others.
  2970. X
  2971. XOptional features are: access control based on pattern matching; remote
  2972. Xusername lookup using the RFC 931 protocol; protection against attacks
  2973. Xfrom hosts that pretend to have someone elses name; protection against
  2974. Xattacks from hosts that pretend to have someone elses network address.
  2975. X
  2976. XThe programs can be installed without requiring any changes to existing
  2977. Xsoftware or configuration files. By default, they just log the remote
  2978. Xhost name and do some sanity checks on the origin the request. No
  2979. Xinformation is exchanged with the remote client process.
  2980. X
  2981. XThe most notable differences with respect to the previous release are:
  2982. X
  2983. X    - Optional protection against attacks from hosts that pretend to
  2984. X    have someone elses network address. For example, the address of a
  2985. X    trusted host within your own network.
  2986. X
  2987. X    - The access control language has been extended with a simple but
  2988. X    powerful operator that greatly simplifies the design of rule sets
  2989. X    (ALL: .foo.edu EXCEPT dialup.foo.edu). Blank lines are permitted,
  2990. X    and long lines can be continued with backslash-newline.
  2991. X
  2992. X    - All configurable stuff, including path names, has been moved into
  2993. X    the Makefile so that you no longer have to hack source code to just
  2994. X    configure the programs.
  2995. X
  2996. X    - Ported to Solaris 2. TLI-based applications not yet supported.
  2997. X    Several workarounds for System V bugs.
  2998. X
  2999. X    - A small loophole in the netgroup lookup code was closed, and the
  3000. X    remote username lookup code was made more portable.
  3001. X
  3002. X    - Still more documentation. The README file now provides tutorial
  3003. X    sections with introductions to client, server, inetd and syslogd.
  3004. X
  3005. XThe default mode of operation should be backwards compatible with
  3006. Xearlier versions.
  3007. X
  3008. X    Wietse Venema (wietse@wzv.win.tue.nl),
  3009. X    Department of Mathematics and Computing Science,
  3010. X    Eindhoven University of Technology,
  3011. X    The Netherlands.
  3012. END_OF_BLURB
  3013. if test 2068 -ne `wc -c <BLURB`; then
  3014.     echo shar: \"BLURB\" unpacked with wrong size!
  3015. fi
  3016. # end of overwriting check
  3017. fi
  3018. if test -f rfc931.c -a "${1}" != "-c" ; then 
  3019.   echo shar: Will not over-write existing file \"rfc931.c\"
  3020. else
  3021. echo shar: Extracting \"rfc931.c\" \(3825 characters\)
  3022. sed "s/^X//" >rfc931.c <<'END_OF_rfc931.c'
  3023. X /*
  3024. X  * rfc931_user() speaks a common subset of the RFC 931, AUTH, TAP and IDENT
  3025. X  * protocols. It consults an RFC 931 etc. compatible daemon on the client
  3026. X  * host to look up the remote user name. The information should not be used
  3027. X  * for authentication purposes.
  3028. X  * 
  3029. X  * Diagnostics are reported through syslog(3).
  3030. X  * 
  3031. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  3032. X  * 
  3033. X  * Inspired by the authutil package (comp.sources.unix volume 22) by Dan
  3034. X  * Bernstein (brnstnd@kramden.acf.nyu.edu).
  3035. X  */
  3036. X
  3037. X#ifndef lint
  3038. Xstatic char sccsid[] = "@(#) rfc931.c 1.4 93/03/07 22:47:52";
  3039. X#endif
  3040. X
  3041. X#include <stdio.h>
  3042. X#include <syslog.h>
  3043. X#include <sys/types.h>
  3044. X#include <sys/socket.h>
  3045. X#include <netinet/in.h>
  3046. X#include <setjmp.h>
  3047. X#include <signal.h>
  3048. X
  3049. X#include "log_tcp.h"
  3050. X
  3051. X#define    RFC931_PORT    113        /* Semi-well-known port */
  3052. X
  3053. X#ifndef RFC931_TIMEOUT
  3054. X#define    RFC931_TIMEOUT    30        /* wait for at most 30 seconds */
  3055. X#endif
  3056. X
  3057. Xextern char *strchr();
  3058. Xextern char *inet_ntoa();
  3059. X
  3060. Xstatic jmp_buf timebuf;
  3061. X
  3062. X/* timeout - handle timeouts */
  3063. X
  3064. Xstatic void timeout(sig)
  3065. Xint     sig;
  3066. X{
  3067. X    longjmp(timebuf, sig);
  3068. X}
  3069. X
  3070. X/* rfc931_name - return remote user name */
  3071. X
  3072. Xchar   *rfc931_name(there)
  3073. Xstruct sockaddr_in *there;        /* remote link information */
  3074. X{
  3075. X    struct sockaddr_in here;        /* local link information */
  3076. X    struct sockaddr_in sin;        /* for talking to RFC931 daemon */
  3077. X    int     length;
  3078. X    int     s;
  3079. X    unsigned remote;
  3080. X    unsigned local;
  3081. X    static char user[256];        /* XXX */
  3082. X    char    buffer[512];        /* YYY */
  3083. X    FILE   *fp;
  3084. X    char   *cp;
  3085. X    char   *result = FROM_UNKNOWN;
  3086. X
  3087. X    /* Find out local address and port number of stdin. */
  3088. X
  3089. X    length = sizeof(here);
  3090. X    if (getsockname(0, (struct sockaddr *) & here, &length) == -1) {
  3091. X    syslog(LOG_ERR, "getsockname: %m");
  3092. X    return (result);
  3093. X    }
  3094. X
  3095. X    /*
  3096. X     * The socket that will be used for user name lookups should be bound to
  3097. X     * the same local IP address as stdin. This will automagically happen on
  3098. X     * hosts that have only one IP network address. When the local host has
  3099. X     * more than one IP network address, we must do an explicit bind() call.
  3100. X     */
  3101. X
  3102. X    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  3103. X    return (result);
  3104. X
  3105. X    sin = here;
  3106. X    sin.sin_port = 0;
  3107. X    if (bind(s, (struct sockaddr *) & sin, sizeof sin) < 0) {
  3108. X    syslog(LOG_ERR, "bind: %s: %m", inet_ntoa(here.sin_addr));
  3109. X    return (result);
  3110. X    }
  3111. X    /* Set up timer so we won't get stuck. */
  3112. X
  3113. X    signal(SIGALRM, timeout);
  3114. X    if (setjmp(timebuf)) {
  3115. X    close(s);                /* not: fclose(fp) */
  3116. X    return (result);
  3117. X    }
  3118. X    alarm(RFC931_TIMEOUT);
  3119. X
  3120. X    /* Connect to the RFC931 daemon. */
  3121. X
  3122. X    sin = *there;
  3123. X    sin.sin_port = htons(RFC931_PORT);
  3124. X    if (connect(s, (struct sockaddr *) & sin, sizeof(sin)) == -1
  3125. X    || (fp = fdopen(s, "w+")) == 0) {
  3126. X    close(s);
  3127. X    alarm(0);
  3128. X    return (result);
  3129. X    }
  3130. X
  3131. X    /*
  3132. X     * Use unbuffered I/O or we may read back our own query. setbuf() must be
  3133. X     * called before doing any I/O on the stream. Thanks for the reminder,
  3134. X     * Paul Kranenburg <pk@cs.few.eur.nl>!
  3135. X     */
  3136. X
  3137. X    setbuf(fp, (char *) 0);
  3138. X
  3139. X    /* Query the RFC 931 server. Would 13-byte writes ever be broken up? */
  3140. X
  3141. X    fprintf(fp, "%u,%u\r\n", ntohs(there->sin_port), ntohs(here.sin_port));
  3142. X    fflush(fp);
  3143. X
  3144. X    /*
  3145. X     * Read response from server. Use fgets()/sscanf() instead of fscanf()
  3146. X     * because there is no buffer for pushback. Thanks, Chris Turbeville
  3147. X     * <turbo@cse.uta.edu>.
  3148. X     */
  3149. X
  3150. X    if (fgets(buffer, sizeof(buffer), fp) != 0
  3151. X    && ferror(fp) == 0 && feof(fp) == 0
  3152. X    && sscanf(buffer, "%u , %u : USERID :%*[^:]:%255s",
  3153. X          &remote, &local, user) == 3
  3154. X    && ntohs(there->sin_port) == remote
  3155. X    && ntohs(here.sin_port) == local) {
  3156. X    /* Strip trailing carriage return. */
  3157. X
  3158. X    if (cp = strchr(user, '\r'))
  3159. X        *cp = 0;
  3160. X    result = user;
  3161. X    }
  3162. X    alarm(0);
  3163. X    fclose(fp);
  3164. X    return (result);
  3165. X}
  3166. END_OF_rfc931.c
  3167. if test 3825 -ne `wc -c <rfc931.c`; then
  3168.     echo shar: \"rfc931.c\" unpacked with wrong size!
  3169. fi
  3170. # end of overwriting check
  3171. fi
  3172. if test -f tcpd.8 -a "${1}" != "-c" ; then 
  3173.   echo shar: Will not over-write existing file \"tcpd.8\"
  3174. else
  3175. echo shar: Extracting \"tcpd.8\" \(6757 characters\)
  3176. sed "s/^X//" >tcpd.8 <<'END_OF_tcpd.8'
  3177. X.TH TCPD 8
  3178. X.SH NAME
  3179. Xtcpd \- access control facility for internet services
  3180. X.SH DESCRIPTION
  3181. X.PP
  3182. XThe \fItcpd\fR program can be set up to monitor incoming requests for
  3183. X\fItelnet\fR, \fIfinger\fR, \fIftp\fR, \fIexec\fR, \fIrsh\fR,
  3184. X\fIrlogin\fR, \fItftp\fR, \fItalk\fR, \fIcomsat\fR and other services
  3185. Xthat have a one-to-one mapping onto executable files.
  3186. X.PP
  3187. XOperation is as follows: whenever a request for internet service
  3188. Xarrives, the \fIinetd\fP daemon is tricked into running the \fItcpd\fP
  3189. Xprogram instead of the desired server. \fItcpd\fP logs the request and
  3190. Xdoes some additional checks. When all is well, \fItcpd\fP runs the
  3191. Xappropriate server program and goes away.
  3192. X.PP
  3193. XOptional features are: pattern-based access control, patterns, remote
  3194. Xusername lookups with the RFC 931 protocol, protection against hosts
  3195. Xthat pretend to have someone elses host name, and protection against
  3196. Xhosts that pretend to have someone elses network address.
  3197. X.SH LOGGING
  3198. XConnections that are monitored by
  3199. X.I tcpd
  3200. Xare reported through the \fIsyslog\fR(3) facility. Each record contains
  3201. Xa time stamp, the remote host name and the name of the service
  3202. Xrequested. The information can be useful to detect unwanted activities,
  3203. Xespecially when logfile information from several hosts is merged.
  3204. X.PP
  3205. XIn order to find out where your logs are going, examine the syslog
  3206. Xconfiguration file, usually /etc/syslog.conf.
  3207. X.SH ACCESS CONTROL
  3208. XOptionally,
  3209. X.I tcpd
  3210. Xsupports a simple form of access control that is based on pattern
  3211. Xmatching.  The access-control software provides hooks for the execution
  3212. Xof shell commands when a pattern fires.  For details, see the
  3213. X\fIhosts_access\fR(5) manual page.
  3214. X.SH HOST NAME VERIFICATION
  3215. XThe authentication scheme of some protocols (\fIrlogin, rsh\fR) relies
  3216. Xon host names. Some implementations believe the host name that they get
  3217. Xfrom any random name server; other implementations are more careful but
  3218. Xuse a flawed algorithm.
  3219. X.PP
  3220. X.I tcpd
  3221. Xverifies the remote host name that is returned by the address->name DNS
  3222. Xserver by looking at the host name and address that are returned by the
  3223. Xname->address DNS server.  If any discrepancy is detected,
  3224. X.I tcpd
  3225. Xconcludes that it is dealing with a host that pretends to have someone
  3226. Xelses host name.
  3227. X.PP
  3228. XIf the sources are compiled with the \*QPARANOID\*U option,
  3229. X.I tcpd
  3230. Xwill drop the connection in case of a host name/address mismatch.
  3231. XOtherwise,
  3232. X.I tcpd
  3233. Xjust pretends that host name lookup failed when logging the connection
  3234. Xand consulting the optional access control tables.
  3235. X.SH HOST ADDRESS SPOOFING
  3236. XBy default,
  3237. X.I tcpd
  3238. Xdisables source-routing socket options on every connection that it
  3239. Xdeals with. This will take care of most attacks from hosts that pretend
  3240. Xto have an address that belongs to someone elses network. UDP services
  3241. Xdo not benefit from this protection.
  3242. X.SH RFC 931
  3243. XWhen RFC 931 lookups are enabled (compile-time option) \fItcpd\fR will
  3244. Xattempt to establish the name of the remote user. This will succeed
  3245. Xonly if the client host runs an RFC 931-compliant daemon.  Remote user
  3246. Xname lookups will not work for datagram-oriented connections, and may
  3247. Xcause noticeable delays in the case of connections from PCs.
  3248. X.SH EXAMPLES
  3249. XThe details of using \fItcpd\fR depend on pathname information that was
  3250. Xcompiled into the program.
  3251. X.SH EXAMPLE 1
  3252. XThis example applies when \fItcpd\fR expects that the original network
  3253. Xdaemons will be moved to a "secret" place.
  3254. X.PP
  3255. XIn order to monitor access to the \fIfinger\fR service, move the
  3256. Xoriginal finger daemon to the "secret" place and install tcpd in the
  3257. Xplace of the original finger daemon. No changes are required to
  3258. Xconfiguration files.
  3259. X.nf
  3260. X.sp
  3261. X.in +5
  3262. X# mkdir /secret/place
  3263. X# mv /usr/etc/in.fingerd /secret/place
  3264. X# cp tcpd /usr/etc/in.fingerd
  3265. X.fi
  3266. X.PP
  3267. XThe example assumes that the network daemons live in /usr/etc. On some
  3268. Xsystems, network daemons live in /usr/sbin or in /usr/libexec, or have
  3269. Xno `in.\' prefix to their name.
  3270. X.SH EXAMPLE 2
  3271. XThis example applies when \fItcpd\fR expects that the network daemons
  3272. Xare left in their original place.
  3273. X.PP
  3274. XIn order to monitor access to the \fIfinger\fR service, perform the
  3275. Xfollowing edits on the \fIinetd\fR configuration file (usually 
  3276. X\fI/etc/inetd.conf\fR or \fI/etc/inet/inetd.conf\fR):
  3277. X.nf
  3278. X.sp
  3279. X.ti +5
  3280. Xfinger  stream  tcp  nowait  nobody  /usr/etc/in.fingerd  in.fingerd
  3281. X.sp
  3282. Xbecomes:
  3283. X.sp
  3284. X.ti +5
  3285. Xfinger  stream  tcp  nowait  nobody  /some/where/tcpd     in.fingerd
  3286. X.sp
  3287. X.fi
  3288. X.PP
  3289. XThe example assumes that the network daemons live in /usr/etc. On some
  3290. Xsystems, network daemons live in /usr/sbin or in /usr/libexec, the
  3291. Xdaemons have no `in.\' prefix to their name, or there is no userid
  3292. Xfield in the inetd configuration file.
  3293. X.PP
  3294. XSimilar changes will be needed for the other services that are to be
  3295. Xcovered by \fItcpd\fR.  Send a `kill -HUP\' to the \fIinetd\fR(8)
  3296. Xprocess to make the changes effective.
  3297. X.SH EXAMPLE 3
  3298. XIn the case of daemons that do not live in a common directory ("secret"
  3299. Xor otherwise), edit the \fIinetd\fR configuration file so that it
  3300. Xspecifies an absolute path name for the process name field. For example:
  3301. X.nf
  3302. X.sp
  3303. X    ntalk  dgram  udp  wait  root  /some/where/tcpd  /usr/local/lib/ntalkd
  3304. X.sp
  3305. X.fi
  3306. X.PP
  3307. XOnly the last component (ntalkd) of the process name will be used for
  3308. Xaccess control and logging.
  3309. X.SH BUGS
  3310. XSome UDP (and RPC) daemons linger around for a while after they have
  3311. Xfinished their work, in case another request comes in.  In the inetd
  3312. Xconfiguration file these services are registered with the \fIwait\fR
  3313. Xoption. Only the request that started such a daemon will be logged.
  3314. X.PP
  3315. XThe program does not work with RPC services over TCP. These services
  3316. Xare registered as \fIrpc/tcp\fR in the inetd configuration file. The
  3317. Xonly non-trivial service that is affected by this limitation is
  3318. X\fIrexd\fR, which is used by the \fIon(1)\fR command. This is no great
  3319. Xloss.  On most systems, \fIrexd\fR is less secure than a wildcard in
  3320. X/etc/hosts.equiv.
  3321. X.PP
  3322. XRPC broadcast requests (for example: \fIrwall, rup, rusers\fR) always
  3323. Xappear to come from the responding host. What happens is that the
  3324. Xclient broadcasts the request to all \fIportmap\fR daemons on its
  3325. Xnetwork; each \fIportmap\fR daemon forwards the request to a local
  3326. Xdaemon. As far as the \fIrwall\fR etc.  daemons know, the request comes
  3327. Xfrom the local host.
  3328. X.SH FILES
  3329. X.PP
  3330. XThe default locations of the host access control tables are:
  3331. X.PP
  3332. X/etc/hosts.allow
  3333. X.br
  3334. X/etc/hosts.deny
  3335. X.SH SEE ALSO
  3336. X.na
  3337. X.nf
  3338. Xhosts_access(5), format of the tcpd access control tables.
  3339. Xsyslog.conf(5), format of the syslogd control file.
  3340. Xinetd.conf(5), format of the inetd control file.
  3341. X.SH AUTHORS
  3342. X.na
  3343. X.nf
  3344. XWietse Venema (wietse@wzv.win.tue.nl),
  3345. XDepartment of Mathematics and Computing Science,
  3346. XEindhoven University of Technology,
  3347. XThe Netherlands.
  3348. X\" @(#) tcpd.8 1.2 93/03/07 22:47:54
  3349. END_OF_tcpd.8
  3350. if test 6757 -ne `wc -c <tcpd.8`; then
  3351.     echo shar: \"tcpd.8\" unpacked with wrong size!
  3352. fi
  3353. # end of overwriting check
  3354. fi
  3355. if test -f hosts_info.c -a "${1}" != "-c" ; then 
  3356.   echo shar: Will not over-write existing file \"hosts_info.c\"
  3357. else
  3358. echo shar: Extracting \"hosts_info.c\" \(788 characters\)
  3359. sed "s/^X//" >hosts_info.c <<'END_OF_hosts_info.c'
  3360. X /*
  3361. X  * hosts_info() returns a string with as much information about the origin
  3362. X  * of a connection as we have: the user name, if known, and the host name,
  3363. X  * or the host address if the name is not available.
  3364. X  * 
  3365. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  3366. X  */
  3367. X
  3368. X#ifndef lint
  3369. Xstatic char sccsid[] = "@(#) hosts_info.c 1.1 92/06/11 22:21:44";
  3370. X#endif
  3371. X
  3372. X#include <stdio.h>
  3373. X
  3374. X#include "log_tcp.h"
  3375. X
  3376. X/* hosts_info - return string with as much about the client as we know */
  3377. X
  3378. Xchar   *hosts_info(client)
  3379. Xstruct from_host *client;
  3380. X{
  3381. X    static char buf[BUFSIZ];        /* XXX */
  3382. X
  3383. X    if (client->user[0] && strcmp(client->user, FROM_UNKNOWN)) {
  3384. X    sprintf(buf, "%s@%s", client->user, FROM_HOST(client));
  3385. X    return (buf);
  3386. X    } else {
  3387. X    return (FROM_HOST(client));
  3388. X    }
  3389. X}
  3390. END_OF_hosts_info.c
  3391. if test 788 -ne `wc -c <hosts_info.c`; then
  3392.     echo shar: \"hosts_info.c\" unpacked with wrong size!
  3393. fi
  3394. # end of overwriting check
  3395. fi
  3396. if test -f hosts_access.3 -a "${1}" != "-c" ; then 
  3397.   echo shar: Will not over-write existing file \"hosts_access.3\"
  3398. else
  3399. echo shar: Extracting \"hosts_access.3\" \(2018 characters\)
  3400. sed "s/^X//" >hosts_access.3 <<'END_OF_hosts_access.3'
  3401. X.TH HOSTS_ACCESS 3
  3402. X.SH
  3403. Xhosts_access, hosts_ctl \- access control library
  3404. X.SH SYNOPSIS
  3405. X.nf
  3406. X#include "log_tcp.h"
  3407. X
  3408. Xint hosts_access(daemon, client)
  3409. Xchar *daemon;
  3410. Xstruct from_host *client;
  3411. X
  3412. Xint hosts_ctl(daemon, client_name, client_addr, client_user)
  3413. Xchar *daemon;
  3414. Xchar *client_host;
  3415. Xchar *client_addr;
  3416. Xchar *client_user;
  3417. X.fi
  3418. X.SH DESCRIPTION
  3419. XThe routines described in this document are part of the \fIlibwrap.a\fR
  3420. Xlibrary. They implement a pattern-based access control language with
  3421. Xoptional shell commands that are executed when a pattern fires.
  3422. X.PP
  3423. XIn all cases, the daemon argument should specify a daemon process name
  3424. X(argv[0] value).  The client host address should be a valid address, or
  3425. XFROM_UNKNOWN if address lookup failed. The client host name and user
  3426. Xname should be empty strings if no information is available,
  3427. XFROM_UNKNOWN if lookup failed, or an actual host or user name.
  3428. X.PP
  3429. Xhosts_access() consults the access control tables described in the
  3430. X\fIhosts_access(5)\fR manual page.  If a match is found, an optional
  3431. Xshell command is executed and the search terminates. hosts_access()
  3432. Xreturns zero if access should be denied.
  3433. X.PP
  3434. Xhosts_ctl() is a wrapper around the hosts_access() routine with a
  3435. Xperhaps more convenient interface.  hosts_ctl() returns zero if access
  3436. Xshould be denied.
  3437. X.SH DIAGNOSTICS
  3438. XProblems are reported via the syslog daemon.
  3439. X.SH SEE ALSO
  3440. Xhosts_access(5), format of the access control tables.
  3441. X.SH FILES
  3442. X/etc/hosts.access, /etc/hosts.deny, access control tables.
  3443. X.SH BUGS
  3444. XThe functions described here do not make copies of their string-valued
  3445. Xarguments.  Beware of data from functions that overwrite their results
  3446. Xupon each call.
  3447. X.sp
  3448. Xhosts_access() uses the strtok() library function. This may interfere
  3449. Xwith other code that relies on strtok().
  3450. X.SH AUTHOR
  3451. X.na
  3452. X.nf
  3453. XWietse Venema (wietse@wzv.win.tue.nl)
  3454. XDepartment of Mathematics and Computing Science
  3455. XEindhoven University of Technology
  3456. XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  3457. X\" @(#) hosts_access.3 1.1 92/06/11 22:21:45
  3458. END_OF_hosts_access.3
  3459. if test 2018 -ne `wc -c <hosts_access.3`; then
  3460.     echo shar: \"hosts_access.3\" unpacked with wrong size!
  3461. fi
  3462. # end of overwriting check
  3463. fi
  3464. if test -f hosts_ctl.c -a "${1}" != "-c" ; then 
  3465.   echo shar: Will not over-write existing file \"hosts_ctl.c\"
  3466. else
  3467. echo shar: Extracting \"hosts_ctl.c\" \(969 characters\)
  3468. sed "s/^X//" >hosts_ctl.c <<'END_OF_hosts_ctl.c'
  3469. X /*
  3470. X  * hosts_ctl() combines the most common applications of the host access
  3471. X  * control library. routine. It bundles its arguments into a from_host
  3472. X  * structure, then calls the hosts_access() access control checker. The host
  3473. X  * name and user name arguments should be empty strings, "unknown" or real
  3474. X  * data. if a match is found, the optional shell command is executed.
  3475. X  * 
  3476. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  3477. X  */
  3478. X
  3479. X#ifndef lint
  3480. Xstatic char sccsid[] = "@(#) hosts_ctl.c 1.1 92/06/11 22:21:48";
  3481. X#endif
  3482. X
  3483. X#include <stdio.h>
  3484. X
  3485. X#include "log_tcp.h"
  3486. X
  3487. X/* hosts_ctl - general interface for the hosts_access() routine */
  3488. X
  3489. Xint     hosts_ctl(daemon, name, addr, user)
  3490. Xchar   *daemon;
  3491. Xchar   *name;
  3492. Xchar   *addr;
  3493. Xchar   *user;
  3494. X{
  3495. X    struct from_host client;
  3496. X    static struct from_host zeros;
  3497. X
  3498. X    client = zeros;
  3499. X    client.name = name;
  3500. X    client.addr = addr;
  3501. X    client.user = user;
  3502. X
  3503. X    return (hosts_access(daemon, &client));
  3504. X}
  3505. END_OF_hosts_ctl.c
  3506. if test 969 -ne `wc -c <hosts_ctl.c`; then
  3507.     echo shar: \"hosts_ctl.c\" unpacked with wrong size!
  3508. fi
  3509. # end of overwriting check
  3510. fi
  3511. if test -f percent_x.c -a "${1}" != "-c" ; then 
  3512.   echo shar: Will not over-write existing file \"percent_x.c\"
  3513. else
  3514. echo shar: Extracting \"percent_x.c\" \(2603 characters\)
  3515. sed "s/^X//" >percent_x.c <<'END_OF_percent_x.c'
  3516. X /*
  3517. X  * percent_x() takes a string and performs %a (host address), %c (client
  3518. X  * info), %h (host name or address), %d (daemon name), %p (process id) and
  3519. X  * %u (user name) substitutions. It aborts the program when the result of
  3520. X  * expansion would overflow the output buffer. Because the result of %<char>
  3521. X  * expansion is typically passed on to a shell process, characters that may
  3522. X  * confuse the shell are replaced by underscores.
  3523. X  * 
  3524. X  * Diagnostics are reported through syslog(3).
  3525. X  * 
  3526. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  3527. X  */
  3528. X
  3529. X#ifndef lint
  3530. Xstatic char sccsid[] = "@(#) percent_x.c 1.2 92/08/24 21:46:22";
  3531. X#endif
  3532. X
  3533. X/* System libraries. */
  3534. X
  3535. X#include <stdio.h>
  3536. X#include <syslog.h>
  3537. X
  3538. Xextern char *strncpy();
  3539. Xextern char *strchr();
  3540. Xextern void exit();
  3541. X
  3542. X/* Local stuff. */
  3543. X
  3544. X#include "log_tcp.h"
  3545. X
  3546. X/* percent_x - do %<char> expansion, abort if result buffer is too small */
  3547. X
  3548. Xvoid    percent_x(result, result_len, str, daemon, client, pid)
  3549. Xchar   *result;
  3550. Xint     result_len;
  3551. Xchar   *str;
  3552. Xchar   *daemon;
  3553. Xstruct from_host *client;
  3554. Xint     pid;
  3555. X{
  3556. X    char   *end = result + result_len - 1;    /* end of result buffer */
  3557. X    char   *expansion;
  3558. X    int     expansion_len;
  3559. X    char    pid_buf[10];
  3560. X    static char ok_chars[] = "1234567890!@%-_=+\\:,./\
  3561. Xabcdefghijklmnopqrstuvwxyz\
  3562. XABCDEFGHIJKLMNOPQRSTUVWXYZ";
  3563. X    char   *cp;
  3564. X
  3565. X    /*
  3566. X     * %a becomes the client address; %c all user and host information we
  3567. X     * have about the client; %d the daemon process name; %h the client host
  3568. X     * name or address; %p the daemon process id; %u the remote user name; %%
  3569. X     * becomes a %, and %other is ignored. We terminate with a diagnostic if
  3570. X     * we would overflow the result buffer. Characters that may confuse the
  3571. X     * shell are mapped to underscores.
  3572. X     */
  3573. X
  3574. X    while (*str) {
  3575. X    if (*str == '%') {
  3576. X        str++;
  3577. X        expansion =
  3578. X        *str == 'a' ? (str++, client->addr) :
  3579. X        *str == 'c' ? (str++, hosts_info(client)) :
  3580. X        *str == 'd' ? (str++, daemon) :
  3581. X        *str == 'h' ? (str++, FROM_HOST(client)) :
  3582. X        *str == 'p' ? (str++, sprintf(pid_buf, "%d", pid), pid_buf) :
  3583. X        *str == 'u' ? (str++, client->user) :
  3584. X        *str == '%' ? (str++, "%") :
  3585. X        *str == 0 ? "" : (str++, "");
  3586. X        expansion_len = strlen(expansion);
  3587. X        for (cp = expansion; *cp; cp++)
  3588. X        if (strchr(ok_chars, *cp) == 0)
  3589. X            *cp = '_';
  3590. X    } else {
  3591. X        expansion = str++;
  3592. X        expansion_len = 1;
  3593. X    }
  3594. X    if (result + expansion_len >= end) {
  3595. X        syslog(LOG_ERR, "shell command too long: %30s...", result);
  3596. X        exit(0);
  3597. X    }
  3598. X    strncpy(result, expansion, expansion_len);
  3599. X    result += expansion_len;
  3600. X    }
  3601. X    *result = 0;
  3602. X}
  3603. END_OF_percent_x.c
  3604. if test 2603 -ne `wc -c <percent_x.c`; then
  3605.     echo shar: \"percent_x.c\" unpacked with wrong size!
  3606. fi
  3607. # end of overwriting check
  3608. fi
  3609. if test -f options.c -a "${1}" != "-c" ; then 
  3610.   echo shar: Will not over-write existing file \"options.c\"
  3611. else
  3612. echo shar: Extracting \"options.c\" \(10084 characters\)
  3613. sed "s/^X//" >options.c <<'END_OF_options.c'
  3614. X /*
  3615. X  * General skeleton for adding options to the access control language. The
  3616. X  * Makefile describes how this alternative language is enabled. Shell
  3617. X  * commands will still be available, be it with a slightly different syntax.
  3618. X  * 
  3619. X  * The code uses a slightly different format of access control rules. It
  3620. X  * assumes that an access control rule looks like this:
  3621. X  * 
  3622. X  * daemon_list : client_list : option : option ...
  3623. X  * 
  3624. X  * An option is of the form "keyword" or "keyword = value". Option fields are
  3625. X  * processed from left to right. Blanks around keywords, "="  and values are
  3626. X  * optional. Blanks within values are left alone.
  3627. X  * 
  3628. X  * Diagnostics are reported through syslog(3).
  3629. X  * 
  3630. X  * Examples of options that are already implemented by the current skeleton:
  3631. X  * 
  3632. X  * user = nobody
  3633. X  * 
  3634. X  * Causes the process to switch its user id to that of "nobody". This normally
  3635. X  * requires root privilege.
  3636. X  * 
  3637. X  * group = tty
  3638. X  * 
  3639. X  * Causes the process to change its group id to that of the "tty" group. In
  3640. X  * order to switch both user and group ids you should normally switch the
  3641. X  * group id before switching the user id.
  3642. X  * 
  3643. X  * setenv = name value
  3644. X  * 
  3645. X  * places a name,value pair into the environment. The value is subjected to
  3646. X  * %<character> expansions.
  3647. X  * 
  3648. X  * spawn = (/usr/ucb/finger -l @%h | /usr/ucb/mail root) &
  3649. X  * 
  3650. X  * Executes (in a background child process) the shell command "finger -l @%h |
  3651. X  * mail root" after doing the %<character> expansions described in the
  3652. X  * hosts_access(5) manual page. The command is executed with stdin, stdout
  3653. X  * and stderr connected to the null device. Because options are processed in
  3654. X  * order, multiple spawn comands can be specified within the same access
  3655. X  * control rule, though "spawn = command1; command2" would be more
  3656. X  * efficient.
  3657. X  * 
  3658. X  * in.ftpd : ... : twist = /bin/echo 421 Some customized bounce message
  3659. X  * 
  3660. X  * Sends some custmized bounce message to the remote client instead of running
  3661. X  * the real ftp daemon. The command is subjected to %<character> expansion
  3662. X  * before execution by /bin/sh. Stdin, stdout and stderr are connected to the
  3663. X  * remote client process. The twist'ed command overlays the current process;
  3664. X  * it makes no sense to specify other options on the same line after a
  3665. X  * "twist". The "twist" option was inspired by Dan Bernstein's shuctl daemon
  3666. X  * wrapper control language.
  3667. X  * 
  3668. X  * umask = value
  3669. X  * 
  3670. X  * Sets the process file creation mask. Value must be an octal number.
  3671. X  * 
  3672. X  * If you compile with -DRFC_OPTION, code is enabled for the following option
  3673. X  * that does selective rfc931 lookups.
  3674. X  * 
  3675. X  * rfc931
  3676. X  * 
  3677. X  * Causes the daemon front ends to look up the remote user name with the RFC
  3678. X  * 931 protocol.
  3679. X  * 
  3680. X  * Warnings:
  3681. X  * 
  3682. X  * This module uses the non-reentrant strtok() library routine. The options
  3683. X  * argument to process_options() is destroyed.
  3684. X  * 
  3685. X  * There cannot be a ":" character in keywords or values. Backslash sequences
  3686. X  * are not yet recognized.
  3687. X  * 
  3688. X  * In case of UDP connections, do not "twist" commands that use the standard
  3689. X  * I/O or read(2)/write(2) routines to communicate with the client process;
  3690. X  * UDP requires other communications primitives.
  3691. X  * 
  3692. X  * In case of errors, use clean_exit() instead of directly calling exit(), or
  3693. X  * your inetd may loop on an UDP request.
  3694. X  */
  3695. X
  3696. X/* System libraries. */
  3697. X
  3698. X#include <sys/types.h>
  3699. X#include <sys/param.h>
  3700. X#include <sys/socket.h>
  3701. X#include <sys/stat.h>
  3702. X#include <netinet/in.h>
  3703. X#include <netdb.h>
  3704. X#include <stdio.h>
  3705. X#include <syslog.h>
  3706. X#include <pwd.h>
  3707. X#include <grp.h>
  3708. X#include <ctype.h>
  3709. X
  3710. Xextern char *strtok();
  3711. Xextern char *strchr();
  3712. Xextern void closelog();
  3713. X
  3714. X/* Local stuff. */
  3715. X
  3716. X#include "log_tcp.h"
  3717. X
  3718. X/* List of functions that implement the options. Add yours here. */
  3719. X
  3720. Xstatic void user_option();        /* execute "user=name" option */
  3721. Xstatic void group_option();        /* execute "group=name" option */
  3722. Xstatic void umask_option();        /* execute "umask=mask" option */
  3723. Xstatic void twist_option();        /* execute "twist=command" option */
  3724. X#ifdef RFC931_OPTION
  3725. Xstatic void rfc931_option();        /* execute "rfc931" option */
  3726. X#endif
  3727. Xstatic void setenv_option();        /* execute "setenv=name value" */
  3728. X
  3729. Xstatic char *chop_string();        /* strip leading and trailing blanks */
  3730. X
  3731. X/* Structure of the options table. */
  3732. X
  3733. Xstruct option {
  3734. X    char   *name;            /* keyword name, case does not matter */
  3735. X    int     need_value;            /* value required or not */
  3736. X    void    (*func) ();            /* function that does the real work */
  3737. X};
  3738. X
  3739. X/* List of known keywords. Add yours here. */
  3740. X
  3741. Xstatic struct option option_table[] = {
  3742. X    "user", 1, user_option,        /* switch user id */
  3743. X    "group", 1, group_option,        /* switch group id */
  3744. X    "umask", 1, umask_option,        /* change umask */
  3745. X    "spawn", 1, shell_cmd,        /* spawn shell command */
  3746. X    "twist", 1, twist_option,        /* replace current process */
  3747. X#ifdef RFC931_OPTION
  3748. X    "rfc931", 0, rfc931_option,        /* do RFC 931 lookup */
  3749. X#endif
  3750. X    "setenv", 1, setenv_option,        /* update environment */
  3751. X    0,
  3752. X};
  3753. X
  3754. Xstatic char whitespace[] = " \t\r\n";
  3755. X
  3756. X/* process_options - process optional access control information */
  3757. X
  3758. Xprocess_options(options, daemon, client)
  3759. Xchar   *options;
  3760. Xchar   *daemon;
  3761. Xstruct from_host *client;
  3762. X{
  3763. X    char   *key;
  3764. X    char   *value;
  3765. X    struct option *op;
  3766. X
  3767. X    /*
  3768. X     * Light-weight parser. Remember, we may be running as root so we need
  3769. X     * code that is easy to comprehend.
  3770. X     */
  3771. X
  3772. X    for (key = strtok(options, ":"); key; key = strtok((char *) 0, ":")) {
  3773. X    if (value = strchr(key, '=')) {        /* keyword=value */
  3774. X        *value++ = 0;
  3775. X        value = chop_string(value);        /* strip blanks around value */
  3776. X        if (*value == 0)
  3777. X        value = 0;            /* no value left */
  3778. X    }
  3779. X    key = chop_string(key);            /* strip blanks around key */
  3780. X    for (op = option_table; op->name; op++)    /* find keyword */
  3781. X        if (strcasecmp(op->name, key) == 0)
  3782. X        break;
  3783. X    if (op->name == 0) {
  3784. X        syslog(LOG_ERR, "bad option or syntax: \"%s\"", key);
  3785. X    } else if (value == 0 && op->need_value) {
  3786. X        syslog(LOG_ERR, "option \"%s\" requires value", key);
  3787. X    } else if (value && op->need_value == 0) {
  3788. X        syslog(LOG_ERR, "option \"%s\" requires no value", key);
  3789. X    } else {
  3790. X        (*(op->func)) (value, daemon, client);
  3791. X    }
  3792. X    }
  3793. X}
  3794. X
  3795. X/* user_option - switch user id */
  3796. X
  3797. X/* ARGSUSED */
  3798. X
  3799. Xstatic void user_option(value, daemon, client)
  3800. Xchar   *value;
  3801. Xchar   *daemon;
  3802. Xstruct from_host *client;
  3803. X{
  3804. X    struct passwd *pwd;
  3805. X    struct passwd *getpwnam();
  3806. X
  3807. X    if ((pwd = getpwnam(value)) == 0) {
  3808. X    syslog(LOG_ERR, "unknown user: \"%s\"", value);
  3809. X    clean_exit(client);
  3810. X    } else if (setuid(pwd->pw_uid)) {
  3811. X    syslog(LOG_ERR, "setuid(%s): %m", value);
  3812. X    clean_exit(client);
  3813. X    }
  3814. X}
  3815. X
  3816. X/* group_option - switch group id */
  3817. X
  3818. X/* ARGSUSED */
  3819. X
  3820. Xstatic void group_option(value, daemon, client)
  3821. Xchar   *value;
  3822. Xchar   *daemon;
  3823. Xstruct from_host *client;
  3824. X{
  3825. X    struct group *grp;
  3826. X    struct group *getgrnam();
  3827. X
  3828. X    if ((grp = getgrnam(value)) == 0) {
  3829. X    syslog(LOG_ERR, "unknown group: \"%s\"", value);
  3830. X    clean_exit(client);
  3831. X    } else if (setgid(grp->gr_gid)) {
  3832. X    syslog(LOG_ERR, "setgid(%s): %m", value);
  3833. X    clean_exit(client);
  3834. X    }
  3835. X}
  3836. X
  3837. X/* umask_option - set file creation mask */
  3838. X
  3839. X/* ARGSUSED */
  3840. X
  3841. Xstatic void umask_option(value, daemon, client)
  3842. Xchar   *value;
  3843. Xchar   *daemon;
  3844. Xstruct from_host *client;
  3845. X{
  3846. X    unsigned mask;
  3847. X    char    junk;
  3848. X
  3849. X    if (sscanf(value, "%o%c", &mask, &junk) != 1 || (mask & 0777) != mask) {
  3850. X    syslog(LOG_ERR, "bad umask: \"%s\"", value);
  3851. X    clean_exit(client);
  3852. X    }
  3853. X    (void) umask(mask);
  3854. X}
  3855. X
  3856. X/* twist_option - replace process by shell command */
  3857. X
  3858. Xstatic void twist_option(value, daemon, client)
  3859. Xchar   *value;
  3860. Xchar   *daemon;
  3861. Xstruct from_host *client;
  3862. X{
  3863. X    char    buf[BUFSIZ];
  3864. X    int     pid = getpid();
  3865. X    char   *error;
  3866. X
  3867. X    percent_x(buf, sizeof(buf), value, daemon, client, pid);
  3868. X
  3869. X    /* Since we will not be logging in the usual way, do it here and now. */
  3870. X
  3871. X    syslog(SEVERITY, "twist from %s to %s", hosts_info(client), buf);
  3872. X    closelog();
  3873. X
  3874. X    /*
  3875. X     * Before switching to the shell, set up stdout and stderr in case the
  3876. X     * Ultrix inetd didn't.
  3877. X     */
  3878. X
  3879. X    (void) close(1);
  3880. X    (void) close(2);
  3881. X    if (dup(0) != 1 || dup(0) != 2) {
  3882. X    error = "dup: %m";
  3883. X    } else {
  3884. X    (void) execl("/bin/sh", "sh", "-c", buf, (char *) 0);
  3885. X    error = "/bin/sh: %m";
  3886. X    }
  3887. X
  3888. X    /* Can get here only in case of errors. */
  3889. X
  3890. X#ifdef LOG_MAIL
  3891. X    (void) openlog(daemon, LOG_PID, FACILITY);
  3892. X#else
  3893. X    (void) openlog(daemon, LOG_PID);
  3894. X#endif
  3895. X    syslog(LOG_ERR, error);
  3896. X    clean_exit(client);
  3897. X}
  3898. X
  3899. X#ifdef RFC931_OPTION
  3900. X
  3901. X/* rfc931_option - look up remote user name */
  3902. X
  3903. X/* ARGSUSED */
  3904. X
  3905. Xstatic void rfc931_option(value, daemon, client)
  3906. Xchar   *value;
  3907. Xchar   *daemon;
  3908. Xstruct from_host *client;
  3909. X{
  3910. X    if (client->sock_type == FROM_CONNECTED) {
  3911. X    if (client->sin == 0) {
  3912. X        syslog(LOG_ERR, "no socket info for username lookup");
  3913. X    } else {
  3914. X        client->user = rfc931_name(client->sin);
  3915. X    }
  3916. X    }
  3917. X}
  3918. X
  3919. X#endif
  3920. X
  3921. X/* setenv_option - set environment variable */
  3922. X
  3923. X/* ARGSUSED */
  3924. X
  3925. Xstatic void setenv_option(value, daemon, client)
  3926. Xchar   *value;
  3927. Xchar   *daemon;
  3928. Xstruct from_host *client;
  3929. X{
  3930. X    char   *var_name;
  3931. X    char   *var_value;
  3932. X    char    buf[BUFSIZ];
  3933. X    int     pid;
  3934. X
  3935. X    /*
  3936. X     * What we get is one string with the name and the value separated by
  3937. X     * whitespace. Find the end of the name. If that is also the end of the
  3938. X     * string, the value is empty.
  3939. X     */
  3940. X
  3941. X    var_value = value + strcspn(value, whitespace);
  3942. X
  3943. X    if (*var_value == 0) {            /* just a name, that's all */
  3944. X    var_name = value;
  3945. X    } else {                    /* expand %stuff in value */
  3946. X    *var_value++ = 0;
  3947. X    var_name = chop_string(value);
  3948. X    pid = getpid();
  3949. X    percent_x(buf, sizeof(buf), var_value, daemon, client, pid);
  3950. X    var_value = chop_string(buf);
  3951. X    }
  3952. X    if (setenv(var_name, var_value, 1)) {
  3953. X    syslog(LOG_ERR, "memory allocation failure");
  3954. X    clean_exit(client);
  3955. X    }
  3956. X}
  3957. X
  3958. X/* chop_string - strip leading and trailing blanks from string */
  3959. X
  3960. Xstatic char *chop_string(start)
  3961. Xregister char *start;
  3962. X{
  3963. X    register char *end;
  3964. X
  3965. X    while (*start && isspace(*start))
  3966. X    start++;
  3967. X
  3968. X    for (end = start + strlen(start); end > start && isspace(end[-1]); end--)
  3969. X     /* void */ ;
  3970. X    *end = 0;
  3971. X
  3972. X    return (start);
  3973. X}
  3974. END_OF_options.c
  3975. if test 10084 -ne `wc -c <options.c`; then
  3976.     echo shar: \"options.c\" unpacked with wrong size!
  3977. fi
  3978. # end of overwriting check
  3979. fi
  3980. if test -f clean_exit.c -a "${1}" != "-c" ; then 
  3981.   echo shar: Will not over-write existing file \"clean_exit.c\"
  3982. else
  3983. echo shar: Extracting \"clean_exit.c\" \(1268 characters\)
  3984. sed "s/^X//" >clean_exit.c <<'END_OF_clean_exit.c'
  3985. X /*
  3986. X  * clean_exit() cleans up and terminates the program. It should be called
  3987. X  * instead of exit when for some reason the real network daemon will not or
  3988. X  * cannot be run. Reason: in the case of a datagram-oriented service we must
  3989. X  * discard the not-yet received data from the client. Otherwise, inetd will
  3990. X  * see the same datagram again and again, and go into a loop.
  3991. X  * 
  3992. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  3993. X  */
  3994. X
  3995. X#ifndef lint
  3996. Xstatic char sccsid[] = "@(#) clean_exit.c 1.1 92/06/11 22:21:52";
  3997. X#endif
  3998. X
  3999. X#include <sys/types.h>
  4000. X#include <sys/socket.h>
  4001. X#include <stdio.h>
  4002. X
  4003. Xextern void exit();
  4004. X
  4005. X#include "log_tcp.h"
  4006. X
  4007. X/* clean_exit - clean up and exit */
  4008. X
  4009. Xvoid    clean_exit(client)
  4010. Xstruct from_host *client;
  4011. X{
  4012. X    char    buf[BUFSIZ];
  4013. X    struct sockaddr sa;
  4014. X    int     size = sizeof(sa);
  4015. X
  4016. X    /*
  4017. X     * Eat up the not-yet received packet. Some systems insist on a non-zero
  4018. X     * source address argument in the recvfrom() call below.
  4019. X     */
  4020. X
  4021. X    if (client->sock_type == FROM_UNCONNECTED)
  4022. X    (void) recvfrom(0, buf, sizeof(buf), 0, &sa, &size);
  4023. X
  4024. X    /*
  4025. X     * Be kind to the inetd. We already reported the problem via the syslogd,
  4026. X     * and there is no need for additional garbage in the logfile.
  4027. X     */
  4028. X
  4029. X    exit(0);
  4030. X}
  4031. END_OF_clean_exit.c
  4032. if test 1268 -ne `wc -c <clean_exit.c`; then
  4033.     echo shar: \"clean_exit.c\" unpacked with wrong size!
  4034. fi
  4035. # end of overwriting check
  4036. fi
  4037. if test -f setenv.c -a "${1}" != "-c" ; then 
  4038.   echo shar: Will not over-write existing file \"setenv.c\"
  4039. else
  4040. echo shar: Extracting \"setenv.c\" \(931 characters\)
  4041. sed "s/^X//" >setenv.c <<'END_OF_setenv.c'
  4042. X /*
  4043. X  * Some systems do not have setenv(). This one is modeled after 4.4 BSD, but
  4044. X  * is implemented in terms of portable primitives only: getenv(), putenv()
  4045. X  * and malloc(). It should therefore be safe to use on every UNIX system.
  4046. X  * 
  4047. X  * If clobber == 0, do not overwrite an existing variable.
  4048. X  * 
  4049. X  * Returns nonzero if memory allocation fails.
  4050. X  * 
  4051. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  4052. X  */
  4053. X
  4054. X#ifndef lint
  4055. Xstatic char sccsid[] = "@(#) setenv.c 1.1 93/03/07 22:47:58";
  4056. X#endif
  4057. X
  4058. X/* setenv - update or insert environment (name,value) pair */
  4059. X
  4060. Xint     setenv(name, value, clobber)
  4061. Xchar   *name;
  4062. Xchar   *value;
  4063. Xint     clobber;
  4064. X{
  4065. X    char   *malloc();
  4066. X    char   *getenv();
  4067. X    char   *cp;
  4068. X
  4069. X    if (clobber == 0 && getenv(name) != 0)
  4070. X    return (0);
  4071. X    if ((cp = malloc(strlen(name) + strlen(value) + 2)) == 0)
  4072. X    return (1);
  4073. X    sprintf(cp, "%s=%s", name, value);
  4074. X    return (putenv(cp));
  4075. X}
  4076. END_OF_setenv.c
  4077. if test 931 -ne `wc -c <setenv.c`; then
  4078.     echo shar: \"setenv.c\" unpacked with wrong size!
  4079. fi
  4080. # end of overwriting check
  4081. fi
  4082. if test -f patchlevel.h -a "${1}" != "-c" ; then 
  4083.   echo shar: Will not over-write existing file \"patchlevel.h\"
  4084. else
  4085. echo shar: Extracting \"patchlevel.h\" \(70 characters\)
  4086. sed "s/^X//" >patchlevel.h <<'END_OF_patchlevel.h'
  4087. X#ifndef lint
  4088. Xstatic char patchlevel[] = "@(#) patchlevel 5.1";
  4089. X#endif
  4090. END_OF_patchlevel.h
  4091. if test 70 -ne `wc -c <patchlevel.h`; then
  4092.     echo shar: \"patchlevel.h\" unpacked with wrong size!
  4093. fi
  4094. # end of overwriting check
  4095. fi
  4096. if test -f strtok.c -a "${1}" != "-c" ; then 
  4097.   echo shar: Will not over-write existing file \"strtok.c\"
  4098. else
  4099. echo shar: Extracting \"strtok.c\" \(2976 characters\)
  4100. sed "s/^X//" >strtok.c <<'END_OF_strtok.c'
  4101. X/*
  4102. X * Copyright (c) 1988 Regents of the University of California.
  4103. X * All rights reserved.
  4104. X *
  4105. X * Redistribution and use in source and binary forms, with or without
  4106. X * modification, are permitted provided that the following conditions
  4107. X * are met:
  4108. X * 1. Redistributions of source code must retain the above copyright
  4109. X *    notice, this list of conditions and the following disclaimer.
  4110. X * 2. Redistributions in binary form must reproduce the above copyright
  4111. X *    notice, this list of conditions and the following disclaimer in the
  4112. X *    documentation and/or other materials provided with the distribution.
  4113. X * 3. All advertising materials mentioning features or use of this software
  4114. X *    must display the following acknowledgement:
  4115. X *    This product includes software developed by the University of
  4116. X *    California, Berkeley and its contributors.
  4117. X * 4. Neither the name of the University nor the names of its contributors
  4118. X *    may be used to endorse or promote products derived from this software
  4119. X *    without specific prior written permission.
  4120. X *
  4121. X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  4122. X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  4123. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  4124. X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  4125. X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  4126. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  4127. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  4128. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  4129. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  4130. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  4131. X * SUCH DAMAGE.
  4132. X */
  4133. X
  4134. X#if defined(LIBC_SCCS) && !defined(lint)
  4135. Xstatic char sccsid[] = "@(#)strtok.c    5.8 (Berkeley) 2/24/91";
  4136. X#endif /* LIBC_SCCS and not lint */
  4137. X
  4138. X#ifdef __STDC__    /* Added for backwards compatibility -- WZV 930122 */
  4139. X#include <stddef.h>
  4140. X#include <string.h>
  4141. X#else
  4142. X#define const
  4143. X#define NULL 0
  4144. X#endif
  4145. X
  4146. Xchar *
  4147. Xstrtok(s, delim)
  4148. X    register char *s;
  4149. X    register const char *delim;
  4150. X{
  4151. X    register char *spanp;
  4152. X    register int c, sc;
  4153. X    char *tok;
  4154. X    static char *last;
  4155. X
  4156. X
  4157. X    if (s == NULL && (s = last) == NULL)
  4158. X        return (NULL);
  4159. X
  4160. X    /*
  4161. X     * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
  4162. X     */
  4163. Xcont:
  4164. X    c = *s++;
  4165. X    for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
  4166. X        if (c == sc)
  4167. X            goto cont;
  4168. X    }
  4169. X
  4170. X    if (c == 0) {        /* no non-delimiter characters */
  4171. X        last = NULL;
  4172. X        return (NULL);
  4173. X    }
  4174. X    tok = s - 1;
  4175. X
  4176. X    /*
  4177. X     * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
  4178. X     * Note that delim must have one NUL; we stop if we see that, too.
  4179. X     */
  4180. X    for (;;) {
  4181. X        c = *s++;
  4182. X        spanp = (char *)delim;
  4183. X        do {
  4184. X            if ((sc = *spanp++) == c) {
  4185. X                if (c == 0)
  4186. X                    s = NULL;
  4187. X                else
  4188. X                    s[-1] = 0;
  4189. X                last = s;
  4190. X                return (tok);
  4191. X            }
  4192. X        } while (sc != 0);
  4193. X    }
  4194. X    /* NOTREACHED */
  4195. X}
  4196. END_OF_strtok.c
  4197. if test 2976 -ne `wc -c <strtok.c`; then
  4198.     echo shar: \"strtok.c\" unpacked with wrong size!
  4199. fi
  4200. # end of overwriting check
  4201. fi
  4202. if test -f fix_options.c -a "${1}" != "-c" ; then 
  4203.   echo shar: Will not over-write existing file \"fix_options.c\"
  4204. else
  4205. echo shar: Extracting \"fix_options.c\" \(1315 characters\)
  4206. sed "s/^X//" >fix_options.c <<'END_OF_fix_options.c'
  4207. X /*
  4208. X  * Routine to disable IP-level socket options. This code was taken from 4.4BSD
  4209. X  * rlogind source, but all mistakes in it are my fault.
  4210. X  *
  4211. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  4212. X  */
  4213. X
  4214. X#ifndef lint
  4215. Xstatic char sccsid[] = "@(#) fix_options.c 1.1 93/03/07 22:48:02";
  4216. X#endif
  4217. X
  4218. X#include <sys/types.h>
  4219. X#include <sys/param.h>
  4220. X#include <netinet/in.h>
  4221. X#include <netdb.h>
  4222. X#include <stdio.h>
  4223. X#include <syslog.h>
  4224. X
  4225. X#include "log_tcp.h"
  4226. X
  4227. X/* fix_options - get rid of IP-level socket options */
  4228. X
  4229. Xfix_options(client)
  4230. Xstruct from_host *client;
  4231. X{
  4232. X#ifdef IP_OPTIONS
  4233. X    unsigned char optbuf[BUFSIZ / 3], *cp;
  4234. X    char    lbuf[BUFSIZ], *lp;
  4235. X    int     optsize = sizeof(optbuf), ipproto;
  4236. X    struct protoent *ip;
  4237. X
  4238. X    if ((ip = getprotobyname("ip")) != 0)
  4239. X    ipproto = ip->p_proto;
  4240. X    else
  4241. X    ipproto = IPPROTO_IP;
  4242. X
  4243. X    if (getsockopt(0, ipproto, IP_OPTIONS, (char *) optbuf, &optsize) == 0
  4244. X    && optsize != 0) {
  4245. X    lp = lbuf;
  4246. X    for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)
  4247. X        sprintf(lp, " %2.2x", *cp);
  4248. X    syslog(LOG_NOTICE,
  4249. X           "connect from %s with IP options (ignored):%s",
  4250. X           hosts_info(client), lbuf);
  4251. X    if (setsockopt(0, ipproto, IP_OPTIONS, (char *) 0, optsize) != 0) {
  4252. X        syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");
  4253. X        clean_exit(client);
  4254. X    }
  4255. X    }
  4256. X#endif
  4257. X}
  4258. END_OF_fix_options.c
  4259. if test 1315 -ne `wc -c <fix_options.c`; then
  4260.     echo shar: \"fix_options.c\" unpacked with wrong size!
  4261. fi
  4262. # end of overwriting check
  4263. fi
  4264. if test -f inet_addr_fix -a "${1}" != "-c" ; then 
  4265.   echo shar: Will not over-write existing file \"inet_addr_fix\"
  4266. else
  4267. echo shar: Extracting \"inet_addr_fix\" \(552 characters\)
  4268. sed "s/^X//" >inet_addr_fix <<'END_OF_inet_addr_fix'
  4269. X#ifndef lint
  4270. Xstatic char sccsid[] = "@(#) inet_addr_fix 1.1 93/03/07 22:48:04";
  4271. X#endif
  4272. X
  4273. X /*
  4274. X  * Some inet_addr() versions return a struct/union instead of a long. You
  4275. X  * have this problem when the compiler complains about illegal lvalues or
  4276. X  * something like that. The following code fixes this mutant behaviour.
  4277. X  * 
  4278. X  * Bug reported by ben@piglet.cr.usgs.gov (Rev. Ben A. Mesander).
  4279. X  */
  4280. X
  4281. Xstatic long fix_inet_addr(string)
  4282. Xchar   *string;
  4283. X{
  4284. X    struct in_addr addr = inet_addr(string);
  4285. X
  4286. X    return (addr.s_addr);
  4287. X}
  4288. X
  4289. X#define inet_addr fix_inet_addr
  4290. END_OF_inet_addr_fix
  4291. if test 552 -ne `wc -c <inet_addr_fix`; then
  4292.     echo shar: \"inet_addr_fix\" unpacked with wrong size!
  4293. fi
  4294. # end of overwriting check
  4295. fi
  4296. echo shar: End of shell archive.
  4297. exit 0
  4298.  
  4299.